Python 全局变量意外行为
Python global variables unexpected behavior
我在下面的 Python (3.8) 示例中发现了我没有预料到的差异。
我们在模块config
中定义了一个全局变量:
config.py
:
global_variable = 80
然后模块 foo
中的两个函数以两种不同的方式使用该全局变量,我认为它们是等效的:
foo.py
:
from config import global_variable
import config
def foo1():
return global_variable
def foo2():
return config.global_variable
最后,我在主脚本中将全局变量设置为 0
后打印两个函数的结果:
main.py
:
import config
import foo
if __name__ == '__main__':
config.global_variable = 0
print("foo1(): ", foo.foo1())
print("foo2(): ", foo.foo2())
但我发现它们有不同的结果。输出为:
foo1(): 80
foo2(): 0
如何解释这种差异?
我可能和你一样是新手,但我很确定只有当全局声明在你要导入的脚本中时,变量才是全局的
这是您使用导入语句的方式。您以不同的方式两次导入同一个文件,因此 python 也将它们视为两次导入。因此,当您将变量的值更改为
config.global_variable = 0
影响
的全局变量
import config
您的 foo.py
文件中的此导入语句。
from config import global_variable
import config
def foo1():
return global_variable # uses from config import global_variable statement
def foo2():
return config.global_variable # uses import config
因此在此处,foo2() returns 更改后的变量值,而 foo1() returns 原始值。如果你想改变 foo1() 的值,那么你必须做这样的事情。
from config import global_variable
import config
import foo
if __name__ == '__main__':
config.global_variable = 0
global_variable = 0
print("foo1(): ", foo.foo1())
print("foo2(): ", foo.foo2())
感谢您之前的回答和评论。他们帮助我理解了这个问题,但我觉得其中 none 是完全清楚的,所以这里是一个答案。
当我问这个问题时,我虽然 from config import global_variable
会在本地包中创建一个新的绑定(或“名称”)global_variable
,但它仍然会绑定到相同的内存位置as config.global_variable
(同一个变量的两个名称)。
然而,似乎是真的 from config import global_variable
在本地包中创建了一个新变量 global_variable
,只是 初始化 的值 config.global_variable
。 (更准确地说,出于效率原因,global_variable
在创建时可能仍指向与 config.global_variable
相同的内存位置,但与正常绑定不同,它在分配一个时开始引用其他内存位置新值)。
因此,当我给global_variable
赋新值时,并没有像原来预期的那样影响config.global_variable
,而是改变了新变量global_variable
的值。
所以看来,如果我想跨模块使用一个变量,我必须始终在所有模块中使用限定形式 config.global_variable
。
我在下面的 Python (3.8) 示例中发现了我没有预料到的差异。
我们在模块config
中定义了一个全局变量:
config.py
:
global_variable = 80
然后模块 foo
中的两个函数以两种不同的方式使用该全局变量,我认为它们是等效的:
foo.py
:
from config import global_variable
import config
def foo1():
return global_variable
def foo2():
return config.global_variable
最后,我在主脚本中将全局变量设置为 0
后打印两个函数的结果:
main.py
:
import config
import foo
if __name__ == '__main__':
config.global_variable = 0
print("foo1(): ", foo.foo1())
print("foo2(): ", foo.foo2())
但我发现它们有不同的结果。输出为:
foo1(): 80
foo2(): 0
如何解释这种差异?
我可能和你一样是新手,但我很确定只有当全局声明在你要导入的脚本中时,变量才是全局的
这是您使用导入语句的方式。您以不同的方式两次导入同一个文件,因此 python 也将它们视为两次导入。因此,当您将变量的值更改为
config.global_variable = 0
影响
的全局变量import config
您的 foo.py
文件中的此导入语句。
from config import global_variable
import config
def foo1():
return global_variable # uses from config import global_variable statement
def foo2():
return config.global_variable # uses import config
因此在此处,foo2() returns 更改后的变量值,而 foo1() returns 原始值。如果你想改变 foo1() 的值,那么你必须做这样的事情。
from config import global_variable
import config
import foo
if __name__ == '__main__':
config.global_variable = 0
global_variable = 0
print("foo1(): ", foo.foo1())
print("foo2(): ", foo.foo2())
感谢您之前的回答和评论。他们帮助我理解了这个问题,但我觉得其中 none 是完全清楚的,所以这里是一个答案。
当我问这个问题时,我虽然 from config import global_variable
会在本地包中创建一个新的绑定(或“名称”)global_variable
,但它仍然会绑定到相同的内存位置as config.global_variable
(同一个变量的两个名称)。
然而,似乎是真的 from config import global_variable
在本地包中创建了一个新变量 global_variable
,只是 初始化 的值 config.global_variable
。 (更准确地说,出于效率原因,global_variable
在创建时可能仍指向与 config.global_variable
相同的内存位置,但与正常绑定不同,它在分配一个时开始引用其他内存位置新值)。
因此,当我给global_variable
赋新值时,并没有像原来预期的那样影响config.global_variable
,而是改变了新变量global_variable
的值。
所以看来,如果我想跨模块使用一个变量,我必须始终在所有模块中使用限定形式 config.global_variable
。