本文實(shí)例講述了Python實(shí)現(xiàn)動(dòng)態(tài)加載模塊、類、函數(shù)的方法。分享給大家供大家參考,具體如下:
動(dòng)態(tài)加載模塊:
方式1:系統(tǒng)函數(shù)__import__()
方式2:imp, importlib 模塊
方式3:exec 函數(shù)
動(dòng)態(tài)加載類和函數(shù)
首先,使用加載模塊,使用內(nèi)置函數(shù)提供的反射方法getattr(),依次按照層級獲取模塊->類/全局方法->類對象/類方法。
test_import_module.py
class ClassA: def test(self): print('test') int_value = 1 str_value = __author__# 全局方法,加載時(shí)會(huì)被調(diào)用print(__file__, 'global function.')if __name__ == '__main__': print(__file__, __name__)test_import_module.py
# 注意:模塊名不包括.py后綴imp_module = 'test_import_class'imp_class = 'ClassA'# 方式1:使用__import__()導(dǎo)入模塊# 導(dǎo)入指定模塊,導(dǎo)入時(shí)會(huì)執(zhí)行全局方法。ip_module = __import__(imp_module)# dir()查看模塊屬性print(dir(ip_module))# 使用getattr()獲取imp_module的類test_class = getattr(ip_module, imp_class)# 動(dòng)態(tài)加載類test_class生成類對象cls_obj = test_class()# 查看對象屬性print(dir(cls_obj))for attr in dir(cls_obj): # 加載非__前綴的屬性 if attr[0] != '_': # 獲取導(dǎo)入obj方法。 class_attr_obj = getattr(cls_obj, attr) # 判斷類屬性是否為函數(shù) if hasattr(class_attr_obj, '__call__'): # 執(zhí)行函數(shù) class_attr_obj() else: # 輸出類屬性值 print(attr, ' type:', type(class_attr_obj), ' value:', class_attr_obj)
輸出結(jié)果
D:/work/python/test_import_class.py global function.['ClassA', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'int_value', 'str_value', 'test']int_value type: <class 'int'> value: 1str_value type: <class 'str'> value: abctest
# 方式2:使用importlib# importlib相比__import__(),操作更簡單、靈活,支持reload()import importlibip_module = importlib.import_module('.', imp_module)ip_module_cls = getattr(ip_module, imp_class)cls_obj = ip_module_cls()if 'int_value' in dir(cls_obj): print(cls_obj.int_value) cls_obj.int_value = 10 print(cls_obj.int_value)# reload()重新加載,一般用于原模塊有變化等特殊情況。# reload()之前該模塊必須已經(jīng)使用import導(dǎo)入模塊。# 重新加載模塊,但原來已經(jīng)使用的實(shí)例還是會(huì)使用舊的模塊,而新生產(chǎn)的實(shí)例會(huì)使用新的模塊,reload后還是用原來的內(nèi)存地址。ip_module = importlib.reload(ip_module)print(getattr(ip_module, imp_class).int_value)# 循環(huán)多次加載相同文件,手動(dòng)修改文件數(shù)據(jù),發(fā)現(xiàn)重新加載后輸出內(nèi)容變更。from time import sleepfor i in range(30): ip_module = importlib.reload(ip_module) print(getattr(ip_module, imp_class).int_value) sleep(3)
希望本文所述對大家Python程序設(shè)計(jì)有所幫助。
新聞熱點(diǎn)
疑難解答
圖片精選