当我们有多个选项,根据不同值调用不同对象时,
不想写很多if—else,就用反射,达到了动态访问、不写死的效果,高内聚、松耦合
反射涉及四个函数:
hasattr: 通过 “字符串” 判断对象的属性或方法是否存在
getattr: 通过 “字符串” 获取对象的属性或方法
setattr: 通过 “字符串” 设置对象的属性或方法
delattr: 通过 “字符串” 删除对象的属性或方法
使用内置函数:
getattr(object, name)
object:是一个对象或者模块
name:一个字符串,代表了对象名称
getattr(commons, 'foobar')
让程序去commons这个模块里,寻找一个名字叫'foobar'的成员,过程相当于把一个字符串变成一个函数名的过程
python反射本质就是基于字符串的事件驱动,利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员
hasattr内置函数,用于判断commons中是否具有某个成员,防止非法输入错误
if hasattr(commons,'foobar'):
func = getattr(commons,'foobar')
func()
# setattr
# 为foo_obj设置一个属性z,值为30
setattr(foo_obj, 'z', 30)
print(hasattr(foo_obj, 'z')) # True
# delattr
delattr(foo_obj, 'x')
print(hasattr(foo_obj, 'x')) # False
动态导入模块
obj = __import__(modules)
modules是字符串
obj = __import__("lib." + modules, fromlist=True)
默认只读最开头的圆点左边的目录,加上fromlist即可以读全部
如果输入了不存在的模块名,只能通过异常处理来解决。
exec和eval,也能执行简单的字符串