Я пытаюсь импортировать разделяемую библиотеку, которая содержит несколько оболочек Python для программы визуализации (конкретнее VisIt ).Эта библиотека реализована таким образом, что сначала импортируется библиотека, которая делает доступными несколько функций, а затем вы вызываете функцию, которая запускает средство визуализации и делает доступным для вызова остальную часть API.Например, в следующем
form visit import *
print dir()
Launch()
print dir()
первый оператор print содержит обычные встроенные функции и пару других функций
['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)
оператор print
в main
будет печатать
['ActivateDatabase', 'AddArgument', 'AddColorTable', 'AddOperator', 'AddPlot', ... ]
, как указано выше, тогда как print
сразу после main
называется print
['AddArgument', 'GetDebugLevel', 'Launch', 'SetDebugLevel', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__warningregistry__']
, как если бы Launch
никогда не вызывалось.
Мой первый вопрос: как мне убедиться, что глобальное пространство имен заполняется вызовом Launch
?
Во-вторых, вызов Version
фактически завершается с ошибкой
NameError: глобальное имя 'Version' не определено
, даже если print "Version" in dir()
возвращаетTrue
.Будет ли эта проблема решена, если я решу свою первую проблему, или это что-то совсем другое?
Пожалуйста, дайте мне знать, если вам нужно больше информации над общей библиотекой.Я не знаю много о том, как это написано, но я могу попытаться выяснить.
Редактировать: После ответа @voithos, вот решение, которое я принял.
Как заявляет @voithos, «Visit использует динамический импорт, который переносит все в локальную область ... при условии, что вы никогда не вызовете visit.Launch()
вне глобальной области».Его (первоначальный) ответ позволяет мне сделать функции, предоставляемые visit.Launch()
, доступными вне (и внутри) моей основной подпрограммы, используя префикс visit.
со всеми этими подпрограммами.
Чтобы импортироватьПроцедуры 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])
, тогда процедуры VisItдоступны на уровне модулей и все выглядит хорошо.
Спасибо @voithos за ваш ответ.