反射就是通过字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动。
首先介绍四个内置函数:
hasattr
setattr
getattr
delattr
下面用例子说明:
class A(object):
def __init__(self):
self.name = "hello"
def say(self):
print("say {}".format(self.name))
a = A()
hasattr(a, 'name') # 注意: 必须是字符串的 name
>>>True
hasattr(a, 'say')
>>>True
getattr(a, 'name')
>>>'hello'
getattr(a, 'say')
>>><bound method A.say of <A object at 0x10e47a6d8>>
setattr(a, 'name', 'world')
a.name
>>>'world'
getattr(a, 'say')()
>>>say world
delattr(a, 'name')
a.name
>>>Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/code.py", line 91, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
AttributeError: 'A' object has no attribute 'name'
delattr(a, 'say') #注意 不能删除实例方法
>>>Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/code.py", line 91, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
AttributeError: say
可能有些人会问,这getattr()
有什么用呢,我直接a.name
,不是照样可以得到实例属性么,没错,如果我们知道这个实例有name属性时,getattr
似乎并没有多大的用处,但是当我们不知道实例中有什么属性时,getattr
就会配上用场了。
class A(object):
def __init__(self):
self.name = "hello"
def say(self):
print("say {}".format(self.name))
def index(self):
if hasattr(self, 'render'):
render = getattr(self, 'render')
return render('index.html')
else:
return '404.html'
a = A()
a.index()
>>>'404.html'
a.render = lambda d: d
a.index()
>>>'index.html'
基于发射就可以实现web框架的部分功能,比如路由等等。
网友评论