所谓的反射,实质上就是“根据字符串形式的内容,去对象中操作成员“。
一、用字符串调用模块
通常调用模块时,使用:import *** 或者from *** import *** 的形式。这里的***是在软件中直接指定好的模块名称。如果根据用户输入的字符串调用模块,需要使用:__import__('***')。
module_name = input('需要调用的模块是:') # 输入shutil后 DD = __import__(module_name) DD.rmtree('codes') # 目录被删除
如:DD = __import__('os') 等价于 import os as DD
二、用字符串去模块中寻找函数并执行
python有四个内置函数与此相关:getattr()、hasattr()、setattr()、delattr()。
(一)getattr(object,name,default=None)调用模块内部函数或变量
# 调用模块内部函数和变量 # 1、调取MD模块中的函数f1,不执行 # ret = getattr(MD,'f1') # 返回函数 # print(type(ret)) # <class 'function'> # 2、调取MD模块中的函数f1,并执行 # ret = getattr(MD,'f1')() # f1()无返回值 # print(type(ret)) # <class 'NoneType'> # # 3、调取MD模块中的函数f2,并执行 # ret = getattr(MD,'f2')() # f2()有返回值 # print(ret,type(ret)) # f2 <class 'str'> # # 4、调取MD模块中的变量 # ret = getattr(MD,'age') # print(ret,type(ret)) # 10 <class 'int'> # # ret = getattr(MD,'name') # print(ret,type(ret)) # lucy <class 'str'> # # ret = getattr(MD,'__file__') # print(ret,type(ret)) # D:\pycharm\dongxuew\lib.py <class 'str'> # # ret = getattr(MD,'__name__') # print(ret) # lib # # 5、调取内容不再模块内,直接报错 # getattr(MD,'f5') # # AttributeError: module 'lib' has no attribute 'f5' # 6、调取内容不再模块内,返回,不报错 getattr(MD,'f5',None)
注意:name使用时需要字符串形式,可以是函数名也可以是变量名。getattr()调取函数时,若要直接执行,后面需要加括号()。调取内容不存在时,默认报错,通过设置参数default可以取消报错。
(二)hasattr(object,name)判断模块中是否含有被调用的内容
ret = hasattr(MD,'__name__') print(ret) # True ret = hasattr(MD,'name') print(ret) # True ret = hasattr(MD,'f4') print(ret) # False ret = hasattr(MD,'f2') print(ret) # True
注意:内容存在时,返回True;内容不存在时,返回False。
(三)setattr(object,name,func)在内存中为模块添加变量或简单函数
print(hasattr(MD,'num')) # False setattr(MD,'num',12) print(hasattr(MD,'num')) # True setattr(MD,'f4',print('f4')) getattr(MD,'f4') # f4
(四)delattr(object,name)在内存中删除模块的变量或者函数
# 删除在内存中新增变量 setattr(MD,'num',12) print(hasattr(MD,'num')) # True delattr(MD,'num') print(hasattr(MD,'num')) # False # 删除模块中函数 print(hasattr(MD,'f1')) # True delattr(MD,'f1') print(hasattr(MD,'f1')) # False
注意:setattr 和 delattr 都是在内存中操作的,与模块文件无关。
浙公网安备 33010602011771号