1 什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数:
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
判断object中有没有一个name字符串对应的方法或属性
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
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 setattr(x, y, v)
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
class BlackMedium: feture=‘Ugly‘ def __init__(self,name,addr): self.name=name self.addr=addr def sell_hourse(self): print(‘【%s】 正在卖房子,傻逼才买呢‘ %self.name) def rent_hourse(self): print(‘【%s】 正在租房子,傻逼才租呢‘ % self.name) # b1=BlackMedium(‘万成置地‘,‘天露园‘) # print(b1.name) #<===> b1.__dic__[‘name‘] print(b1.__dict__) """setattr 判断是否有属性""" # # b1.name # # b1.sell_hourse # print(hasattr(BlackMedium,‘feture‘)) #有对应的数据属性feture,返回True # print(hasattr(BlackMedium,‘sdfasf‘)) #没有对应的方法或属性 返回False # print(hasattr(b1,‘name‘)) #True # print(hasattr(b1,‘sell_hourse‘)) #True # print(hasattr(b1,‘selasdfasdfsadfasdfasdfasdfasdl_hourse‘)) #False """setattr 获取属性""" # print(getattr(b1,‘name‘)) #万成置地 # print(getattr(b1,‘rent_hourse‘)) #<bound method BlackMedium.rent_hourse of <__main__.BlackMedium object at 0x000001CDFB8C9710>> # func=getattr(b1,‘rent_hourse‘) # func() #【万成置地】 正在租房子,傻逼才租呢 # print(getattr(b1,‘rent_hourseasdfsa‘)) #没有则报错 # print(getattr(b1,‘rent_hourseasdfsa‘,‘没有这个属性‘)) #没有则返回设置的默认值:没有这个属性 """setattr 设置属性""" # b1.sb=True # print(b1.__dict__) #{‘name‘: ‘万成置地‘, ‘addr‘: ‘天露园‘, ‘sb‘: True} setattr(b1,‘sb‘,True) setattr(b1,‘sb1‘,123) setattr(b1,‘name‘,‘SB‘) #有则改 没有则加 setattr(b1,‘func‘,lambda x:x+1) setattr(b1,‘func1‘,lambda self:self.name+‘sb‘) print(b1.__dict__) print(b1.func) print(b1.func(10)) print(b1.func1(b1)) """delattr 删除属性""" # del b1.sb # del b1.sb1 delattr(b1,‘sb‘) delattr(b1,‘func‘) print(b1.__dict__)
class Foo(object): staticField = "old boy" def __init__(self): self.name = ‘wupeiqi‘ def func(self): print("from the func()...") return ‘func‘ @staticmethod def bar(): return ‘bar‘ print(getattr(Foo, ‘staticField‘)) print(getattr(Foo, ‘func‘)) getattr(Foo, ‘func‘)(1) # from the func()... print(getattr(Foo, ‘bar‘))
"""反射当前模块成员""" import sys def s1(): print(‘s1‘) def s2(): print(‘s2‘) this_module = sys.modules[__name__] #A way to get a handle to the current running module in Python,即得到当前运行文件及路径 print(this_module) print(__name__) print(hasattr(this_module, ‘s1‘)) #True getattr(this_module, ‘s2‘)() #s2
导入其他模块,利用反射查找该模块是否存在某个方法
def test(): print(‘from module_test.py the test()‘)
import module_test as obj #obj.test() print(hasattr(obj,‘test‘)) #True getattr(obj,‘test‘)()
""" 程序目录: module_test.py index.py 当前运行文件: index.py """
有俩程序员,一个Alex,一个是egon,Alex在写程序的时候需要用到egon所写的类,但是egon去跟女朋友度蜜月去了,还没有完成他写的类,Alex想到了反射,使用了反射机制Alex可以继续完成自己的代码,等egon度蜜月回来后再继续完成类的定义并且去实现Alex想要的功能。总之反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
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(‘处理其他的逻辑‘)
举例:
import importlib mt = importlib.import_module(‘fanse_module.module_test‘) mt.test() #from module_test.py the test()
原文:https://www.cnblogs.com/XJT2018/p/10887099.html