Python命名空间在内置与全局之间?
根据我的理解,Python 有以下几种最外层的命名空间:
内置命名空间 - 这个命名空间在整个解释器中都是全局的,所有在这个解释器实例中运行的脚本都可以访问。
全局命名空间 - 这个命名空间在一个模块内是全局的,也就是说在一个文件中。
我在寻找一个介于这两者之间的命名空间,想要在主脚本中共享一些变量给被调用的模块。
比如,script.py 文件:
import Log from Log
import foo from foo
log = Log()
foo()
还有 foo.py 文件:
def foo():
log.Log('test') # I want this to refer to the callers log object
我希望能够多次调用 script.py,并且在每次调用时,将模块级别的 log 对象暴露给 foo 方法。
有没有人知道这样做是否可能?
虽然传递 log 对象并不会太麻烦,但我正在处理一大段从 Javascript 移植过来的代码。我也明白这会对调用 foo 的部分造成一些限制,要求它必须暴露自己的 log 对象。
谢谢,
保罗
3 个回答
其实,我找到了我想要的东西。
这个技巧实际上是用到了 PLY,而我就是在这里发现的。
这个库的代码可能会在运行时出现错误,这样就可以访问调用者的堆栈信息。
没有这样的范围。你需要要么把它添加到内置的范围里,要么把相关的对象传递过去。
在内置模块和全局模块之间并没有一个“命名空间”,不过你可以很简单地创建自己的命名空间,并把它们用名字放进 sys.modules
里,这样其他模块就可以“导入”它们了(最好不要用 from ... import
这种写法,因为它会带来很多问题,当然也不要用你自己发明的 import ... from
这种写法,这样会直接报语法错误)。比如,在 script.py
里:
import sys
import types
sys.modules['yay'] = types.ModuleType('yay')
import Log
import foo
yay.log = Log.Log()
foo.foo()
在 foo.py
里:
import yay
def foo():
yay.log.Log('test')
不要害怕带有前缀的名字——它们是好东西!就像《Python之禅》的最后一句话(也就是 import this
)所说的:
Namespaces are one honking great idea -- let's do more of those!
你可以更简单地创建和使用“更多这样的东西”——只需给你的名字加上前缀(把它们放在合适的命名空间里)而不是坚持使用不合适的简单名字。使用带前缀的名字可以让很多事情变得简单,而对于那些固执于简单名字的人来说,很多事情可能会变得非常麻烦,甚至几乎无法实现!-)