一、反射的概念
反射是指程序可以访问、检测和修改它本身状态或者行为的一种能力(自省)
二、python中反射的四个函数
hasattr(object,name)
可以检查一个对象之中是否有该属性,若存在返回True,不存在则返回False,name必须为字符串类型。getattr(object,name,default=None)
可以获得一个对象的属性值,若存在则直接返回值;不存在则会报错,如果设置了default,那么会返回default。setattr(object,name,value)
可以为一个对象设置新增属性,或者修改原属性的值。delattr(object,name)
三、反射的实际应用
反射可以实现先定义好接口,接口只有在被完成之后才会真正执行,这实现了即插即用,完成一种后期绑定
# 某个ftp类还没有实现具体功能
class Ftpclient:
def __init__(self,addr):
print('正在连接服务器[%s]'%addr)
self.addr = addr
# 因此可以设定一个逻辑,若有此方法的时候执行,没有这个方法就跳过
f1 = FtpClient('192.168.1.1')
if hasattr(f1,'get')
func_get = getattr(f1,'get')
func_get()
else:
print('不存在此方法')
四、反射函数的实现的内置方法
__getattr__
class Foo:
x = 1
def __init__(self,y):
self.y = y
# 重写__getattr__方法
def __getattr__(self,item):
print('执行__getattr__')
getattr(f1,'y')
#没有任何返回
getattr(f1,'z')
#执行__getattr__
#__getattr__方法只有在寻找一个不存在的属性时才会执行
__setattr__
class Foo:
x = 1
def __init__(self,y):
self.y = y
# 重写__setattr__方法
def __setattr__(self,key,value):
print('执行__setattr__')
#self.key = value 此种方法会引起无限递归
self.__dict__[key] = value
#赋值操作的本质是对底层的字典进行赋值操作
__delattr__
def __setattr__(self,item):
print('执行__delattr__')
self.__dict__.pop(item)
重写反射方法的应用实例
包装文件读写方法
class FileHandle:
def __init__(self,filename,mode='r',encoding='utf-8'):
#类初始化拿到文件句柄
self.file = open(filename,mode,encoding=encoding)
self.mode = mode
self.encodeing = encoding
def __getattr__(self,item):
return getattr(self.file,item)
f1 = FileHandle('a.txt','r+')
f1.write('111111\n')
#f1实例本身没有wirte方法————》转到__getattr__方法中
#在getattr,返回f1.file文件句炳中write方法的内存地址