python类命名空间和全局命名空间_python – 导入共享库和全局命名空间

我正在尝试导入一个共享库,其中包含许多用于可视化程序的

Python包装器(特定于

VisIt).这个库的实现方式是首先导入库,这使得一些函数可用,然后调用一个函数来启动visualisaion查看器并使其余的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)

main中的print语句将打印出来

['ActivateDatabase', 'AddArgument', 'AddColorTable', 'AddOperator', 'AddPlot', ... ]

如上所述,而在main之后的打印称为打印

['AddArgument', 'GetDebugLevel', 'Launch', 'SetDebugLevel', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__warningregistry__']

好像从未调用过Launch.

我的第一个问题是如何通过调用Launch来确保填充全局命名空间?

其次,对Version的调用实际上失败了,错误

NameError: global name ‘Version’ is not defined

即使dir()中的print“Version”返回True.如果我解决了我的第一个问题,这个问题是否会得到解决,还是完全是另一回事?

如果您需要有关共享库上方的更多信息,请与我们联系.我不太了解它是如何写的,但我可以试着找出来.

编辑:在@voithos的回答之后,以下是我采用的解决方案.

正如@voithos所说,“访问使用动态导入,将所有内容带到本地范围……假设您永远不会在全局范围之外调用visit.Launch().”他的(初始)答案允许我通过visit.Launch()使函数可用,使用前缀访问在我的主程序的外部(和)中使用.所有这些惯例.

要从访问导入*导入VisIt例程,以便可以在没有访问的情况下调用它们.前缀我修改@voithos在main中使用setattr到以下内容

# 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的回答.

最佳答案 看来,Visit使用动态导入,将所有内容都带到了本地范围.基本上,他们假设你永远不会在全球范围之外调用visit.Launch().启动函数全部用C语言编写,所以我不确定它是如何导入的.

一种解决方法是将名称从本地范围重新分配到另一个范围. (例如,进入您导入的访问模块)以下是一个示例:

import sys

import visit

def main():

visit.Launch()

# Loop through the locals that were just imported

# and assign the names to the visit module

loc = locals()

for key in loc:

setattr(visit, key, loc[key])

return 0

if __name__=="__main__":

ret = main()

print dir(visit)

sys.exit(ret)

如果您想将名称分配给全局范围,则可以将循环修改为:

loc = locals()

glob = globals()

for key in loc:

glob[key] = loc[key]

但请注意:执行此操作将覆盖之前定义的任何冲突符号名称.例如,如果您定义了Version()函数,则Visit模块中的Version()将覆盖您定义的旧版本.因此,除非你真的需要,否则通常不要用名称来混淆全局范围.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值