標籤:錯誤 str roc cut 載入 asc instance **kwargs line
Python中動態建立類執行個體簡介
在Java中我們可以通過反射來根據類名建立類執行個體,那麼在Python我們怎麼實作類別似功能呢?
其實在Python有一個builtin函數import,我們可以使用這個函數來在運行時動態載入一些模組。如下:
def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return obj
例子
首先我們建一個目錄 my_modules,其中包括三個檔案
* init.py: 模組檔案
* my_module.py: 測試用的模組
* my_another_module: 另一個測試用的模組
my_module.py
from my_modules.my_another_module import *class MyObject(object): def test(self): print ‘MyObject.test‘ MyObject1().test() MyObject2().test() MyAnotherObject().test()class MyObject1(object): def test(self): print ‘MyObject1.test‘class MyObject2(object): def test(self): print ‘MyObject2.test‘
my_another_module.py
class MyAnotherObject(object): def test(self): print ‘MyAnotherObject.test‘
test.py
def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return objobj = createInstance("my_modules.my_module", "MyObject")obj.test()
MyObject.testMyObject1.testMyObject2.testMyAnotherObject.test
pyinstaller整合
對於使用pyinstaller打包的應用程式,如果使用上面的代碼,運行打包後的程式會出現下面的錯誤
Traceback (most recent call last): File "test.py", line 12, in <module> obj = createInstance("my_modules.my_module", "MyObject") File "test.py", line 7, in createInstance module_meta = __import__(module_name, globals(), locals(), [class_name])ImportError: No module named my_modules.my_moduleFailed to execute script test
這裡錯誤的原因是 pyinstaller 在打包分析類的時候沒有分析到 my_modules 下面的模組,所以運行報錯。
解決辦法一:
在 test.py 中把 my_modules 下的模組手動 import,見下面代碼中的第一行。這種方法最簡單,但是顯然不太好。
import my_modules.my_moduledef createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return objobj = createInstance("my_modules.my_module", "MyObject")obj.test()
解決辦法二:
在使用 pyinstaller 打包的時候,指定 “–hidden-import”,如下
pyinstaller -D --hidden-import my_modules.my_module test.py
解決辦法三:
動態修改 python 運行時path,見下面代碼中的前兩行,其中path我們可以通過環境變數或者參數傳遞進來。顯然這種方法要比前兩種方法靈活的多。
import syssys.path.append(...)def createInstance(module_name, class_name, *args, **kwargs): module_meta = __import__(module_name, globals(), locals(), [class_name]) class_meta = getattr(module_meta, class_name) obj = class_meta(*args, **kwargs) return objobj = createInstance("my_modules.my_module", "MyObject")obj.test()
轉載請以連結形式標明本文連結
本文連結:http://blog.csdn.net/kongxx/article/details/65626418
Python中動態建立類執行個體