Python:在其中的模块和类之间共享全局变量

emi*_*ish 35 python scope module global-variables

我知道可以在Python中跨模块共享全局变量.但是,我想知道这可能的程度和原因.例如,

global_mod.py

x = None
Run Code Online (Sandbox Code Playgroud)

mid_access_mod.py

from global_mod import *

class delta:
    def __init__(self):
        print x
Run Code Online (Sandbox Code Playgroud)

bot_modif_mod.py

import mid_access_mod
import global_mod

class mew:
    def __init__(self):
        global_mod.x = 5

def main():
    m = mew()
    d = mid_access_mod.delta()
Run Code Online (Sandbox Code Playgroud)

即使所有模块共享全局变量x,也会打印None.为什么会这样?似乎x在mid_access_mod.py中被评估,然后由mew()在bot_modif_mod.py中分配.

Ned*_*der 37

发生这种情况是因为您使用的是不可变值(int和None),导入变量就像按值传递事物,而不是通过引用传递事物.

如果您创建了global_mod.xa列表并操纵了它的第一个元素,它将按预期工作.

当你这样做from global_mod import x,你正在创建一个名称x与为同一值的模块中xglobal_mod.对于像函数和类这样的东西,这可以像你期望的那样工作,因为人们(通常)以后不会重新分配这些名称.

正如亚历克斯指出的那样,如果你使用import global_mod,那么global_mod.x,你将避免这个问题.您在模块中定义的名称将global_mod始终引用您想要的模块,然后使用属性访问来获取x最新的值x.

  • 我认为你的回答是误导性的.问题主要不是因使用可变或不可变类型而引起的,而是使用`from modulename import*`而不是`import modulename`.如果您使用emish的代码并将global_mod.py更改为`x = ['起始列表']`然后将bot_modif_mod.py中的重新分配更改为`global_mod.x = ['new list']`您将发现这个打印"['起始列表']".真正的问题,正如Alex Martinelli所说的那样是`from modulename import*`snapshots.我希望其他用户不会像我一样混淆. (4认同)

Ale*_*lli 26

from whatever import *不是一个很好的成语在代码中使用-它的目标用户的使用,如果有的话,在交互式会话作为快捷方式来节省一些打字.它基本上"快照"了那个时间点模块中的所有名称 - 如果你重新绑定任何这些名字,快照将变得陈旧,并且随之而来的是各种各样的问题.而这只是你通过使用可怜的from ... import *构造注册的无法解决的混乱的开始.

想要我的建议吗?忘记你曾经听说过现有的构造,永远不会再使用它.使用import global_mod as m和始终使用后合格的名称,如m.x-限定的名称是这样比单纯barenames要容易上手得多,并在Python更强大的是,它甚至不是滑稽.(声明的as m一部分import是完全可选的,基本上是为了简洁目的而存在,或者有时是为了解决名称冲突的一些问题;如果你觉得它很方便使用它,因为它没有缺点,但不要感到被迫或甚至敦促使用,如果你认为没有必要).