Pythonにおける動的作成クラスの例

6150 ワード

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

まず、カタログを作ります。modulesは、3つのファイル*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 obj

obj = createInstance("my_modules.my_module", "MyObject")
obj.test()
MyObject.test
MyObject1.test
MyObject2.test
MyAnotherObject.test
pyinstaller統合
pyinstallerでパッケージ化したアプリケーションに対して、上のコードを使うと、パッケージを実行した後のプログラムに次のエラーが発生します。
Traceback (most recent call last):
  File "test.py", line 12, in 
    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_module
Failed to execute script test
ここのエラーの原因はpyinstallerが分析類を包装する時my_まで分析していないからです。modulesの下のモジュールなので、エラーが発生しました。
解決方法一:
test.pyの中でmyをmodules下のモジュールは手動でimportします。下のコードの最初の行を参照してください。この方法が一番簡単ですが、明らかにあまり良くないです。
import my_modules.my_module

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

obj = createInstance("my_modules.my_module", "MyObject")
obj.test()
解決方法二:
pyinstallerを使用して包装する場合は、「–hidden-inmport」を指定します。以下の通りです。
pyinstaller -D --hidden-import my_modules.my_module test.py
解決方法三:
pythonの運転時のpathを動的に修正します。ここでPAthは環境変数またはパラメータを通して伝達できます。この方法は前の2つの方法よりずっと柔軟であることは明らかである。
import sys
sys.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 obj

obj = createInstance("my_modules.my_module", "MyObject")
obj.test()
転載はリンク形式で本文のリンクを明示してください。http://blog.csdn.net/kongxx/article/details/65626418