在python中反射就是基于字符串的形式去对象(模块)中操作其成员,要借助hasattr(),getattr(),setattr(),delattr()这几个内置函数。
*attr()系列函数可以在各种对象下工作,不限于类和实例。当使用这些函数是,传入的正在处理的对象作为第一个参数, 第二个参数是这些属性名的字符串形式。在操作obj.attr时,相当于调用*attr(obj, 'attr')。
hasattr()函数是布尔型的,判断一个对象是否有一个特定的属性,一般用于访问某属性前检查。
getattr()是取得对象的某属性
setattr()是赋值给对象某属性
delattr()是从一个对象中删除属性
例如: class myClass(object): def __init__(self): ¦ self.foo = 100 # hasattr() myInst = myClass() ret = hasattr(myInst, 'foo') print(ret) # True # getattr() ret = getattr(myInst, 'foo') print(ret) # 100 # setattr() setattr(myInst, 'ugly', 'alex') ret = getattr(myInst, 'ugly') print(ret) # alex # delattr() delattr(myInst, 'ugly') ret = hasattr(myInst, 'ugly') print(ret) # False
反射实例: 有一个lib目录,里面存放的是一些通用的模块 ▾lib/ common.py #!/usr/bin/env python # coding=utf-8 def login(): print('login') def logout(): print('logout') home.py #!/usr/bin/env python # coding=utf-8 def home(): print('home') import lib.common as common import lib.home as home def run(): inp = input('>> 请输入要访问的函数:') if inp == 'login': ¦ common.login() elif inp == 'logout': ¦ common.logout() elif inp == 'home': ¦ home.home() else: ¦ print('404') if __name__ == '__main__': run() >> 请输入要访问的函数:login login >> 请输入要访问的函数:home home 但是如果common.py和home.py成千上万个函数,要在run里写成千上万个elif语句完成?显然不现实,可以通过使用__import__导入模块来实现。 使用__import__导入例子 __import__(模块名字),如果从一个包中导入模块__import__(lib.common),如果没有加fromlist=True,只会返回lib,而不会返回common。 def run(): inp = input('>> 请输入要访问的函数:') # common/login m, f = inp.split('/') # common/login obj = __import__('lib.' + m, fromlist=True) if hasattr(obj, f): ¦ func = getattr(obj, f) # 在obj对象查找f属性 ¦ func() else: ¦ print('404') if __name__ == '__main__': run() >> 请输入要访问的函数:home/home home >> 请输入要访问的函数:common/login login