10

だから私は、次のような「from x import x」ステートメントの束を変えようとしています:

from class_foo import class_foo

ダイナミックなものに。ディレクトリへのパスを渡して、そこにあるすべてのモジュールをインポートしようとしています。

def dynamicImport(dirPath):
    filez = os.listdir(dirPath)
    for file in filez:
        if "class" in file:
            oname = file[:-3] #cut off the file extension, trivial

            imp_statement = "from " + oname + " import " + oname
            #when I print imp_statement, I can verify it's being concatenated correctly

            exec(imp_statement)

この関数を実行してパスを渡すと、ステートメント文字列が適切に作成され、エラーは発生しませんが、後でインポートされたオブジェクトの 1 つにアクセスしようとすると、次のようになります。

foo = class_foo()

NameError: name 'class_foo' is not defined

明らかに私は何か間違ったことをしています。どんな助けでも大歓迎です。

4

5 に答える 5

12

exec関数のローカル名前空間で import ステートメントを実行しているため、名前が定義されている場所です。この名前空間は、関数が終了するとなくなり、何も残されません。おそらくあなたが望むのは のようなものですexec imp_statement in globals()

__import__()string-munging の代わりに使用しないのはなぜですか? 次に、モジュールへの参照を取得します。次に、モジュールオブジェクトを使用してクラス参照をgetattr()探し出し、それをに挿入できますglobals()(または、辞書を呼び出し元に戻して、呼び出し元がそれを処理できますglobals().update())。

import sys, os

def getClasses(directory):
    classes = {}
    oldcwd = os.getcwd()
    os.chdir(directory)   # change working directory so we know import will work
    for filename in os.listdir(directory):
        if filename.endswith(".py"):
            modname = filename[:-3]
            classes[modname] = getattr(__import__(modname), modname)
    os.setcwd(oldcwd)
    return classes

globals().update(getClasses(r"C:\plugin_classes"))

そんな感じ。globals()または、関心のあるグローバル変数を壊す可能性のあるモジュールで更新するのではなく、クラスを辞書に残してそこから参照するだけです。

classes = getClasess(r"C:\plugin_classes")
for clas in classes.itervalues():
    instance = clas(1, 2, 3)       # instantiate
    instance.dosomething_cool(42)  # call method
于 2012-06-19T20:17:01.123 に答える
9

Python >= 2.7 にはimportlibがあります (以前のバージョンの Python で importlib を使用するには、 pip install importlibを実行できます)。

module = importlib.import_module("path.to.module")
MyClass = module.MyClass
于 2015-03-11T23:15:34.370 に答える
-2

Python を扱うのは久しぶりです。しかし、「おなめ」が文字列であるという事実に問題があると思います。行 from class_foo import class_fooは文字列ではありません。骨の折れるオプションの 1 つは、すべてのインポートを含むまったく新しい .py ファイルをコードで作成することです。したがって、現在のすべてのファイルと新しいインポートを、基本的に .py で終わるテキスト ファイルに書き込みます。

于 2012-06-19T20:15:56.037 に答える
-3

__import__関数を見てください

于 2012-06-19T20:15:35.823 に答える