Spa*_*cey 10 python import global-variables
我无法理解为什么在使用时从另一个模块导入全局变量可以按预期工作import,但在使用from x import *全局变量时似乎不会在其自己的模块内更新
假设我有 2 个文件,其中一个.py:
def change(value):
global x
x = value
x = "start"
Run Code Online (Sandbox Code Playgroud)
和两个.py:
from one import *
print x
change("updated")
print x
Run Code Online (Sandbox Code Playgroud)
我期望:
start
updated
Run Code Online (Sandbox Code Playgroud)
但我明白...
start
start
Run Code Online (Sandbox Code Playgroud)
如果我正常导入模块,它会按预期工作
import one
print one.x
one.change("updated")
print one.x
Run Code Online (Sandbox Code Playgroud)
结果...
start
updated
Run Code Online (Sandbox Code Playgroud)
鉴于我无法更改 ony.py 对全局变量的使用(不是我的错),并且 Two.py 是 one.py 的一种包装*,我真的很想避免one.在两个中使用名称空间.py 为了一个顽固的变量。
如果不可能的话,对正在发生的事情进行新手级的解释可能会帮助我避免再次陷入这样的困境。我知道 one.x 正在更新,但 Two.x 不尊重更新,但我不知道为什么。
Jon*_*tts 10
您可以将包视为字典。包中的每个函数和变量都被列为该字典中的键,您可以使用 来查看globals()。
当您从另一个包导入对象时,您将以某个名称(通常相同,也可以不同)将该对象的引用复制到您自己的包中import <var> as <name>。
通过设置另一个包中的值,您可以使用新值覆盖该包中的密钥,但您将引用保留为旧值。
我们可以用 dicts 来类比来演示这个过程:
# Our 'packages'
one = {'x': 'start'}
two = {}
# Equivalent of our import
two['x'] = one['x']
# Variable updated in `one'
one['x'] = 'updated'
# ... and accessed in `two`
print(two['x']) # Still 'start'
Run Code Online (Sandbox Code Playgroud)
我们不会two仅仅因为我们覆盖了 中的值而期望字典被更新one。
只要不通过覆盖变量来破坏指针,就可以修改对象。例如,如果x是一个字典,您可以更改字典内的值,并且两个变量仍然指向同一个对象。
或者,您可以将变量附加到函数,如下所示:
def change(value):
change.x = value
Run Code Online (Sandbox Code Playgroud)
这通过确保我们改变同一个对象来完成相同的工作。
更好的答案可能是将两个项目包装在一个对象中,如果它们需要一起移动:
class Changer:
x = 'start'
@classmethod
def change(cls, value):
cls.x = value
Run Code Online (Sandbox Code Playgroud)
然而此时,我们可以直接将值修改为属性:
Changer.x = 'updated'
Run Code Online (Sandbox Code Playgroud)
这可能是最简单的。