全局变量和模块导入



我已经使用Python多年了,为分发创建新的模块仍然令人困惑和难以理解;这真的很令人沮丧。 我需要一位专家来解释这一点。

我最近发现,在子模块中设置全局变量的行为会有所不同,具体取决于模块在__init__.py文件中的导入方式。

我有这样的设置:

prime.py

import sub
sub.somevar = False
sub.show()

sub.py

somevar = True
def show():
global somevar
print("somevar is {}".format(somevar))

此代码生成预期的输出:

somevar is False.

当 main.py 和 sub.py 位于同一目录中时。 当我使用setuptools将sub作为单独的可安装模块时,它停止工作。

我的sub可安装模块目录结构如下所示:

# ls
setup.py sub README.md
# ls sub
__init__.py sub.py 

其中__init__.py包含文本:

from .sub import *

此设置似乎非常适合安装和分发模块,适用于 Python2 和 Python3。

问题是现在当我用prime.py导入全局变量设置时,全局变量设置被破坏了;任何从prime.py设置somevar的尝试都不会像预期的那样改变sub.py函数的变量。 我得到输出:

somevar is True

这到底是怎么回事? 为什么 python 模块导入如此挑剔?

它与您的项目结构无关,而与您导入项目结构的方式无关。

我认为这很容易理解。由于somevar是一种值类型,当您使用隐式from x import somevarfrom x import *时,您会在当前命名空间中获得somevar的副本。

而且因为它只是一个副本,所以更改它不会更改子模块中的somevar

但如果somevar是一个列表,例如:

# In sub.py
somevar = [True]

你把它改成

# In prime.py
somevar[0] = False

然后它就会起作用。

为了快速修复,您可以简单地使用"setter"getter"行为:

prime.py

import sub
sub.set_somevar(False)
myFalseVar = sub.get_somevar()

sub.py

somevar = True
def get_somevar():
global somevar
return somevar
def set_somevar(var):
global somevar
somevar = var

相关内容

  • 没有找到相关文章

最新更新