一、什么是反射??
在面向对象的思想中,把对象能够访问、查询、修改自身的状态或行为称为“反射”。
二、python中的反射
Python思想:一切事物皆为对象。
在python中,可以通过字符串的的形式来操作对象的属性。这种行为称之为python中的反射。
三、python实现反射(自省)的手段:
通过4个内置函数来实现:hasattr(object,name) getattr(object,name,default=None) setattr(x,y,v) delattr(x,y)
-
hasattr(object,name)
#判断object中有没有一个name字符串对应的方法或属性存在返回True,不存在返回False
def delattr(x, y): # real signature unknown; restored from __doc__
"""
Deletes the named attribute from the given object.
delattr(x, 'y') is equivalent to ``del x.y''
"""
pass
-
getattr(object,name,default=None)
def getattr(object, name, default=None): # known special case of getattr
"""
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
"""
pass# 其中default表示没有找到该属性时所返回的提示。。。
-
setattr(object,name,value)
def setattr(x, y, v): # real signature unknown; restored from __doc__
"""
Sets the named attribute on the given object to the specified value.
setattr(x, 'y', v) is equivalent to ``x.y = v''
"""
pass
-
delattr(x,y)
def delattr(x, y): # real signature unknown; restored from __doc__
"""
Deletes the named attribute from the given object.
delattr(x, 'y') is equivalent to ``del x.y''
"""
pass
注意:不仅仅是实例对象才能使用反射,类本身也是对象,所以类也可以用反射,即类也可以作为object参数参入到上述四个函数中去。例如:
class Foo(object):
staticField = "old boy"
def __init__(self):
self.name = 'wupeiqi'
def func(self):
return 'func'
@staticmethod
def bar():
return 'bar'
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')
类也是对象
再如,文件再python中也被看作是对象,所以一个文件也能用上述四种方法来操作。
#新建一个a.py文件,该文件下定义两个变量x和y x=111 y=222 import sys obj1=sys.modules[__name__]#__name__当前程序所在的模块的名称 print(hasattr(obj1,'z')) #如果能找到名为x的属性,返回True,这里返回的是True
四、为什么使用“反射”
好处一:实现可插拔机制
假设场景:有两个文件需要同时被开发,但是其中一个文件开发进度较慢,可能会影响到另一个文件的开发,这是利用“反射”机制,可以先避开另一个文件的开发进度。。。
class FtpClient:
'ftp客户端,但是还么有实现具体的功能'
def __init__(self,addr):
print('正在连接服务器[%s]' %addr)
self.addr=addr
#from module import FtpClient
f1=FtpClient('192.168.1.1')
if hasattr(f1,'get'):
func_get=getattr(f1,'get')
func_get()
else:
print('---->不存在此方法')
print('处理其他的逻辑')
好处二:动态导入模块(基于反射原理,获取当前的模块的成员)

