如何创建跨模块变量?
__debug__
这个变量很有用,因为它会影响到每一个模块。如果我想创建一个同样好用的变量,我该怎么做呢?
这个变量(我们就叫它 'foo' 吧)不需要是真正意义上的全局变量,也就是说,如果我在一个模块里改变了 foo,其他模块不一定要跟着更新。只要我能在导入其他模块之前设置好 foo,然后其他模块能看到相同的值就可以了。
12 个回答
我认为在很多情况下,使用一些全局变量是有意义的,这样可以简化编程,特别是在一些紧密关联的模块之间。基于这个想法,我想详细讲讲如何创建一个全局变量模块,并让需要使用这些变量的模块去导入它。
当只有一个这样的模块时,我把它命名为“g”。在这个模块里,我为每个我想当作全局变量的变量设置默认值。在每个使用这些变量的模块中,我不会用“from g import var”这种方式导入,因为这样只会创建一个局部变量,它只在导入时从g中初始化。我大多数时候会用g.var的形式来引用这些变量,而“g.”这个前缀时刻提醒我,这个变量可能被其他模块访问。
如果某个全局变量在模块中的某个函数里经常被使用,那么这个函数可以创建一个局部副本:var = g.var。不过,要注意的是,对var的赋值是局部的,想要更新全局的g.var,必须在赋值时明确引用g.var。
另外,你也可以有多个这样的全局变量模块,供不同的模块组共享,这样可以让管理变得更有条理。我给全局变量模块起短名字,是为了避免代码中出现太多冗余的内容。只需一点经验,1到2个字符的名字就能让人记住。
你仍然可以给g.x赋值,即使x在g中还没有定义,这样其他模块也能访问g.x。不过,尽管解释器允许这样做,但这种方式不太直观,我会尽量避免。因为这样可能会因为拼写错误而意外创建一个新的g中的变量。有时候,查看dir(g)可以帮助发现这些意外出现的变量名。
如果你需要一个可以在多个模块之间共享的全局变量,可能简单的全局模块级变量就足够了。
a.py:
var = 1
b.py:
import a
print a.var
import c
print a.var
c.py:
import a
a.var = 2
测试:
$ python b.py
# -> 1 2
现实中的例子:Django的global_settings.py(不过在Django应用中,设置是通过导入对象 django.conf.settings
来使用的)。
我并不支持这个解决方案,但如果你在 __builtin__
模块里添加一个变量,那么在任何包含了 __builtin__
的模块中都可以像使用全局变量一样访问这个变量——默认情况下,所有模块都是这样。
a.py 文件包含
print foo
b.py 文件包含
import __builtin__
__builtin__.foo = 1
import a
结果是会打印出 "1"。
补充说明: __builtin__
模块在本地被称为 __builtins__
,这就是为什么有些答案之间会有差异的原因。另外要注意,在 Python 3 中,__builtin__
被改名为 builtins
。