该__debug__
变量很方便,部分原因是它影响每个模块.如果我想创建另一个以相同方式工作的变量,我该怎么做?
变量(让我们是原始的并称之为'foo')并不一定是真正的全局变量,因为如果我在一个模块中更改foo,它会在其他模块中更新.如果我可以在导入其他模块之前设置foo然后他们会看到相同的值,我会没事的.
如果您需要一个全局跨模块变量,那么简单的全局模块级变量就足够了.
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__
- 这是其中两个答案之间存在差异的原因.另请注意,__builtin__
已builtins
在python3中重命名为.
定义一个模块(称之为"globalbaz")并在其中定义变量.使用此"伪全局"的所有模块都应导入"globalbaz"模块,并使用"globalbaz.var_name"引用它.
无论更改的位置如何,都可以使用,您可以在导入之前或之后更改变量.导入的模块将使用最新值.(我在玩具示例中对此进行了测试)
为了澄清,globalbaz.py看起来像这样:
var_name = "my_useful_string"
我相信在很多情况下它确实有意义,并且它简化了编程,使得一些全局变量在几个(紧密耦合的)模块中是已知的.本着这种精神,我想详细说明一个全局变量模块的想法,这些模块由那些需要引用它们的模块导入.
当只有一个这样的模块时,我将其命名为"g".在其中,我为我打算视为全局的每个变量分配默认值.在使用其中任何一个的每个模块中,我不使用"from g import var",因为这只会产生一个局部变量,该变量仅在导入时从g初始化.我以g.var和"g"的形式创建了大多数引用.作为一个不断提醒我,我正在处理其他模块可能访问的变量.
如果要在模块中的某个函数中频繁使用此类全局变量的值,则该函数可以生成本地副本:var = g.var.但是,重要的是要认识到var的赋值是本地的,并且如果没有在赋值中显式引用g.var,则无法更新全局g.var.
请注意,您还可以使用模块的不同子集共享多个此类全局模块,以使事情更加严格控制.我为我的全局模块使用短名称的原因是为了避免因出现它们而过多地混淆代码.只有一点点经验,它们只有1或2个字符就足够了.
当g尚未在g中定义时,仍然可以对gx进行赋值,然后另一个模块可以访问gx但是,即使解释器允许它,这种方法也不是那么透明,我确实避免它.由于作业的变量名称中存在拼写错误,因此仍有可能在g中意外创建新变量.有时,对dir(g)的检查有助于发现可能由此类事故引起的任何惊喜名称.
您可以将一个模块的全局变量传递给另一个模块:
在模块A中:
import module_b my_var=2 module_b.do_something_with_my_globals(globals()) print my_var
在模块B中:
def do_something_with_my_globals(glob): # glob is simply a dict. glob["my_var"]=3
全局变量通常是一个坏主意,但您可以通过分配到__builtins__
:
__builtins__.foo = 'something' print foo
此外,模块本身是您可以从任何模块访问的变量.因此,如果您定义一个名为的模块my_globals.py
:
# my_globals.py foo = 'something'
然后你也可以在任何地方使用它:
import my_globals print my_globals.foo
使用模块而不是修改__builtins__
通常是一种更简洁的方法来完成这种全局变量.
您已经可以使用模块级变量执行此操作.无论从哪个模块导入,模块都是相同的.因此,您可以将变量作为模块级变量放在任何有意义的模块中,并将其访问或从其他模块分配给它.最好调用一个函数来设置变量的值,或者使它成为某个单例对象的属性.这样,如果您最终需要在变量更改时运行某些代码,则可以在不破坏模块外部接口的情况下执行此操作.
这通常不是一种很好的方式 - 使用全局变量很少 - 但我认为这是最干净的方法.