我想導入一個共享庫,其中包含一些可視化程序的Python包裝(具體來說就是VisIt)。這個庫的實現方式是首先導入一個庫,它提供了一些可用的函數,然後調用一個函數來啓動visualisaion查看器,並讓其餘的API可以調用。例如,在下面的導入一個共享庫和全局命名空間
form visit import *
print dir()
Launch()
print dir()
第一打印語句包含通常的內建和幾個其他功能
['AddArgument', 'GetDebugLevel', 'Launch', 'SetDebugLevel', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__warningregistry__']
和第二打印產量
['ActivateDatabase', 'AddArgument', 'AddColorTable', 'AddOperator', 'AddPlot', ... ]
等
我想改爲在一個函數內調用Launch
(所以我可以親將參數傳遞給Launch
)。但是,當我這樣做時,在調用Launch
後可用的函數不在全局名稱空間中,而是在函數本地的名稱空間中。因此,在下面的例子中
import sys
from visit import *
def main():
Launch()
print dir()
if "Version" in dir()
print Version() # This is made available by call to Launch() above
return 0
if __name__=="__main__":
ret = main()
print dir()
sys.exit(ret)
內main
的print
語句將打印
['ActivateDatabase', 'AddArgument', 'AddColorTable', 'AddOperator', 'AddPlot', ... ]
如上,main
被稱爲打印
['AddArgument', 'GetDebugLevel', 'Launch', 'SetDebugLevel', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__warningregistry__']
而剛過print
彷彿Launch
從來沒有調用。
我的第一個問題是如何確保通過調用Launch
來填充全局名稱空間?
其次,調用Version
實際上失敗,並錯誤
NameError: global name 'Version' is not defined
即使print "Version" in dir()
回報True
。如果我解決了我的第一個問題,這個問題會得到解決嗎?還是完全是其他問題?
如果您需要共享庫上方的更多信息,請讓我知道。我不太瞭解它是如何寫的,但我可以試着弄清楚。
編輯:按照@voithos的回答,以下是我採用的解決方案。
正如@voithos所述,「訪問使用動態導入,將所有內容帶到本地範圍......假設您永遠不會在全球範圍外呼叫visit.Launch()
」。他的(初始)答案允許我使用visit.Launch()
提供的功能在我的主程序的外部(和內部)使用,使用前綴visit.
以及所有這些例程。
要導入訪問程序如from visit import *
,讓他們可以在沒有visit.
前綴叫我修改@voithos'使用setattr
在main
以下
# Loop through the local namespace and add the names that were just
# imported to the module namespace
loc = locals()
for key in loc:
setattr(sys.modules[__name__], key, loc[key])
然後訪問程序都可以在模塊級別,一切似乎都很好。
感謝@voithos的回答。
我最初發布我的編輯作爲答案,但覺得將它作爲我的問題的更新會更好。 – Chris