本文實例講述了Python實現動態加載模塊、類、函數的方法。分享給大家供大家參考,具體如下:
動態加載模塊:
方式1:系統函數__import__() 
方式2:imp, importlib 模塊 
方式3:exec 函數
動態加載類和函數
首先,使用加載模塊,使用內置函數提供的反射方法getattr(),依次按照層級獲取模塊->類/全局方法->類對象/類方法。
test_import_module.py
class ClassA:  def test(self):    print('test')  int_value = 1  str_value = __author__# 全局方法,加載時會被調用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__()導入模塊# 導入指定模塊,導入時會執行全局方法。ip_module = __import__(imp_module)# dir()查看模塊屬性print(dir(ip_module))# 使用getattr()獲取imp_module的類test_class = getattr(ip_module, imp_class)# 動態加載類test_class生成類對象cls_obj = test_class()# 查看對象屬性print(dir(cls_obj))for attr in dir(cls_obj): # 加載非__前綴的屬性 if attr[0] != '_': # 獲取導入obj方法。 class_attr_obj = getattr(cls_obj, attr) # 判斷類屬性是否為函數 if hasattr(class_attr_obj, '__call__'): # 執行函數 class_attr_obj() else: # 輸出類屬性值 print(attr, ' type:', type(class_attr_obj), ' value:', class_attr_obj)
輸出結果
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()之前該模塊必須已經使用import導入模塊。# 重新加載模塊,但原來已經使用的實例還是會使用舊的模塊,而新生產的實例會使用新的模塊,reload后還是用原來的內存地址。ip_module = importlib.reload(ip_module)print(getattr(ip_module, imp_class).int_value)# 循環多次加載相同文件,手動修改文件數據,發現重新加載后輸出內容變更。from time import sleepfor i in range(30):  ip_module = importlib.reload(ip_module)  print(getattr(ip_module, imp_class).int_value)  sleep(3)            
新聞熱點
疑難解答