1

私はPythonを1週間使用していますが、動的インポートの問題に直面しています。クラスが定義されているTest.pyファイルがあります。別のファイルからTest.pyを動的にインポートした後、このクラスを使用したいと思います。

私の最終的な目標はもっと複雑ですが、それを単純化しましたが、それでも同じ問題が発生します。

ファイル:Test.py

class Test :
    def __init__ ( self ) :
        print ( "instance" )

ファイル:Main.py

def allImports ( ) :
    __import__ ( "Test" )

私が得るもの:

>>> import Main
>>> Main.allImports()
>>> myInstance = Test ()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
NameError: name 'Test' is not defined

Test.pyのどの要素をインポートする必要があるかをfromlistで指定することはできません。これは、それらを知っているはずがないためです。

私は何をすべきか ?

4

4 に答える 4

3

あなたの意図に近い解決策のために:

import importlib
def allImports(globals):
    mod = importlib.import_module('Test', globals['__name__'])

    try:
        keys = mod.__all__
    except AttributeError:
        keys = dir(mod)

    for key in keys:
        if not key.startswith('_'):
            globals[key] = getattr(mod, key)

# …

allImports(globals())
Test # should work, you can also look into dir(Test) to find the class.

モジュールに上記のコードがない場合は__all__、名前空間が何か激しいものになります。必ず定義するか、必要なものだけをインポートするように__all__変更してください。allImports()(たとえば、クラスのみ、またはモジュールで定義されたクラスのみ。この部分は実際にはユースケースによって異なります。)

于 2012-07-05T13:15:24.270 に答える
1

このコードは__import__ ( "Test" )ローカル変数を作成するため、関数の外部からアクセスすることはできません。

   def allImports ( ) :
        __import__ ( "Test" )

試す:

def allImports ( ) :
   test= __import__ ( "Test" )
   return test   #return the module

>>> import Main
>>> x=Main.allImports()  #store the returned module in x
>>> myInstance = x.Test ()
instance
>>>myInstance
<Test.Test instance at 0x011D7F80>
于 2012-07-05T13:03:35.930 に答える
1

__import__()モジュールのロードに使用する場合は、次の場所で検索する必要がありsys.modulesます。

>>> import sys
>>> import Main
>>> Main.allImports()
>>> myInstance = sys.modules['Test'].Test()
instance
>>>

詳細については、ドキュメントおよびここここ、およびここを参照してください。

于 2012-07-05T13:09:37.503 に答える
1

__import__グローバル名前空間もローカル名前空間も魔法のように変更しません。

モジュールとクラスはPythonの第一級市民です。つまり、Pythonの他のオブジェクトとして使用できます(名前にバインドし、パラメーターとして関数に渡し、関数から値として返します)。

def allImports():
    return __import__("Test")

Test_module = allImports()
Test = Test_module.Test # class
test_instance = Test()

上記のコードが関数内にある場合は、Testグローバル名前空間に配置しますglobals()['Test'] = Test。ほとんどの場合、これは必要ないことに注意してください。関数内のグローバル名前空間を変更せずに、やりたいことを行うためのより良い方法があります。

代わりにの使用__import__()はお勧めしませんimportlib.import_module()

モジュールの名前とクラスがわかっている場合は、モジュールレベルで書くことができます。

from Test import Test
于 2012-07-05T13:52:15.600 に答える