のようなセキュリティ ホールを除いて、名前がどこかで定義されているか、別のモジュールからインポートされていない限り、名前をeval使用することはできません。別のモジュールからの値に自動的かつ静かにアクセスさせる方法はありません。amapper.pymapper.pymapper.pya
さらに、例のように dict でのみ使用している場合はa.foo、dict が作成されるとすぐに評価されます。実際に関数を呼び出すまで待つ必要はありません。辞書を作成するために評価されるとすぐに、何がa.foo何であるかがわからないため失敗しaます。
この 2 番目の問題は、要素を関数でラップすることで回避できます (簡潔にするためにラムダを使用します)。
Mapper = {'test': lambda: a.foo}
. . . aしかし、どうにかして内部で利用できるようにならない限り、これはまだ役に立ちませんmapper.py。
1つの可能性は、「ミステリー」オブジェクトでパラメーター化Mapperし、そのオブジェクトを外部から渡すことです。
# mapper.py
Mapper = {'test': lambda a: a.foo}
# other module
from mapper import Mapper
Mapper['test'](a)()
または、提案されたのと同様に、何らかの方法でオブジェクトをmgilson「登録」できます。これにより、オブジェクトを一度だけ渡して登録することができ、呼び出しごとに渡す必要がなくなります。aMappera
# mapper.py
Mapper = {'test': lambda a: Mapper['a'].foo}
# other module
from mapper import Mapper
Mapper['a'] = a
Mapper['test']()()
最後に 2 組の括弧があることに注意してください。1 組はラムダを評価して呼び出したい関数を抽出するためのもので、2 番目の組は実際にその関数を呼び出すためのものです。参照として使用する代わりにMapper['a']、モジュール レベルの変数を使用して、同様の処理を行うことができます。
# mapper.py
Mapper = {'test': lambda: a.foo}
# other module
import mapper
Mapper = mapper.Mapper
mapper.a = a
Mapper['test']()()
import mapperこれは、他のモジュールでモジュール変数を設定するために行う必要があることに注意してください。
Mapper通常の dict の代わりにカスタムクラス for を使用し、そのクラス__getitem__に「既知の場所」を調べて (たとえば、モジュール変数を読み取って) 評価のベースとして使用することで、これをいくらか合理化できaます。ただし、それはより重いソリューションになります。
肝心なのは、未定義の variable を使用するevalコードを(再び、または他のそのような穴を使用せずに) 記述し、別のモジュールで変数を定義して、それを自動的に認識することができないということです。使用する値を「伝える」コード行がどこかにある必要があります。mapper.pyaamapper.pymapper.pya