0

__init__.py* .pyファイルのすべての関数をディレクトリから名前空間(ディレクトリの名前)にインポートするファイルを作成しようとしています。ロジックを以下に示します。

for f in os.listdir(wd):
    if not f.endswith('.py') or f == '__init__.py':
        continue
    names = get_public_functions(open(wd + f))
    try:
        mod = __import__(f[:-3], fromlist=names)
        for fn in names:
            fun = getattr(mod, fn)
            setattr(sys.modules[__name__], fn, fun)
    except Exception as e: 
        for fn in names:
            setattr(sys.modules[__name__], fn, lambda: str(e))

したがって、ファイルに構文エラーがある場合でも、関数はインポートされますが、構文エラーが(文字列として)返されることがわかります。

イライラするのは、複数のファイルに構文エラーがある場合、次のようなことを期待していることです。

mymodule.fn() => error1,
mymodule.fn2() => error1 (these were from the first file),
mymodule.fn3() => error2 etc.

最後のエラーメッセージのみが表示されます。exceptエラーはブロック内にあるに違いないと思いますが、理解できません。誰か助けてもらえますか?

4

1 に答える 1

1

eの値を、作成したラムダのスコープにバインドする必要があります。むしろ、str(e)結果をラムダにバインドします。

error = str(e)
for fn in names:
    setattr(sys.modules[__name__], fn, lambda error=error: error

現在、各ラムダには、その時点での値を格納するキーワード パラメータがありますerrorerrorパラメータはデフォルト値を持つキーワード パラメータであるため、ラムダは引数で呼び出された場合でも機能します。

別の方法は、新しい関数スコープを作成することです。

def errorfunction(error):
    return lambda: error

error = str(e)
for fn in names:
    setattr(sys.modules[__name__], fn, errorfunction(error)
于 2013-03-11T15:24:37.863 に答える