[英]How to resolve a global variable in a module?
我有一個腳本如下
from mapper import Mapper
class A(object):
def foo(self):
print "world"
a = A()
a.foo()
Mapper['test']()
使用mapper.py
文件中定義的Mapper
:
Mapper = {'test': a.foo}
我想在哪里定義一個函數調用,引用一個未在mapper.py
定義的對象,但在原始代碼中。 但是上面的代碼給出了錯誤
NameError: name 'a' is not defined
這使得那種感覺,作為a
沒有定義mapper.py
本身。 但是,是否可以更改代碼以使代碼在主代碼本身中執行名稱解析,或者使用globals
或其他東西?
為了解決這個問題,我可以將mapper.py
的實現指定為文本,並在主代碼中使用eval
,但我想避免使用eval
。
附加信息:
mapper.py
a
是,或什么CLAS它被實例化。 除非像eval
這樣的安全漏洞,否則無法在mapper.py
使用名稱a
,除非該名稱在mapper.py
某處定義或從其他模塊導入。 沒有辦法讓mapper.py
自動並靜默地訪問來自不同模塊的值a
。
另外,如果你只是在你的例子中的dict中使用它, a.foo
將在創建dict時立即進行評估。 它不會等到你實際調用該函數; 只要它計算a.foo
創建字典,它會失敗,因為它不知道是什么a
是。
您可以通過將元素包裝在函數中來解決第二個問題(為簡潔起見使用lambda):
Mapper = {'test': lambda: a.foo}
。 。 。 但這仍然不會幫助,除非你能以某種方式得到a
可用的內部mapper.py
。
一種可能性是通過“神秘”對象對Mapper
進行參數化,然后從外部傳遞該對象:
# mapper.py
Mapper = {'test': lambda a: a.foo}
# other module
from mapper import Mapper
Mapper['test'](a)()
或者,類似於mgilson
建議的,你可以用Mapper
以某種方式“注冊”對象a
。 這使您可以傳遞對象a
唯一的一次注冊,然后你不必把它傳遞每一個呼叫:
# mapper.py
Mapper = {'test': lambda a: Mapper['a'].foo}
# other module
from mapper import Mapper
Mapper['a'] = a
Mapper['test']()()
注意那里的兩組括號:一組用於評估lambda並提取你想要調用的函數,另一組用於實際調用該函數。 您可以使用模塊級變量執行類似的處理,而不是使用Mapper['a']
作為引用:
# mapper.py
Mapper = {'test': lambda: a.foo}
# other module
import mapper
Mapper = mapper.Mapper
mapper.a = a
Mapper['test']()()
請注意,這需要您執行import mapper
以便在該其他模塊中設置模塊變量。
您可以通過使用Mapper
的自定義類而不是常規字典來簡化這一點,並讓該類在其__getitem__
執行一些工作以查看“已知位置”(例如,讀取某個模塊變量)以用作基礎評估a
。 不過,這將是一個更重的解決方案。
底線是你根本不能(再次,沒有使用eval
或其他這樣的漏洞)在mapper.py
中編寫使用未定義變量a
,然后在另一個模塊中定義變量a
並讓mapper.py
自動知道關於那個。 必須有一些代碼行,某處“講述” mapper.py
什么價值a
你想使用它。
我不知道我完全跟隨,而是a
可以“注冊”這是法Mapper
由具有參考映射器的任何地方:
#mapping.py
Mapper = {}
接着:
#main.py
from mapping import Mapper
#snip
a = A()
Mapper['test'] = a.foo #put your instance method into the Mapper dict.
#snip
Mapper['test']()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.