first.py
myGlobal = "hello"
def changeGlobal():
myGlobal="bye"
second.py
from first import *
changeGlobal()
print myGlobal
我得到的输出是
hello
尽管我认为它应该是
bye
为什么在调用changeGlobal()
函数后全局变量myGlobal
没有改变?
尝试:
def changeGlobal():
global myGlobal
myGlobal = "bye"
实际上,那也不起作用。当你使用import *
时,你会创建一个新的全局模块myGlobal
,它对于你打算进行的更改是免疫的(只要你不改变变量,见下文)。你可以使用以下代码替代:
import nice
nice.changeGlobal()
print nice.myGlobal
或者:
myGlobal = "hello"
def changeGlobal():
global myGlobal
myGlobal="bye"
changeGlobal()
然而,如果你的全局变量是可变容器,那么你现在持有一个对可变容器的引用,并且能够看到对它所做的更改:
myGlobal = ["hello"]
def changeGlobal():
myGlobal[0] = "bye"
# x.py
import y
def f():
global x
x = 6
def main():
global x
x = 3
f()
y.g()
if __name__ == ’__main__’:
main()
以及 y.py:
# y.py
def g():
global x
x += 1
Python全局变量并不是真正的全局
正如wassimans在上面指出的,它们实际上是定义它们的模块的作用域内的属性(或包含定义它们的函数的模块)。
人们遇到的第一个混淆(错误)是没有意识到函数有一个本地名称空间,并且在函数中设置变量会使它成为函数的本地变量,即使他们原本想要更改封闭模块中同名的(全局)变量。(在函数中声明该名称的"global"语句,或在设置之前访问(全局)变量。)
人们遇到的第二个混淆(错误)是每个模块(即导入的文件)都包含自己的所谓"全局"名称空间。我猜python认为世界(地球)就是这个模块--也许我们正在寻找跨越多个地球的"通用"变量。
第三个混淆(我现在开始理解的)是在__main__
模块中的"全局"变量在哪里?也就是说,如果您从命令行以交互模式启动python,或者如果您调用python脚本(从命令行键入foo.py的名称)--没有导入可以使用名称的模块。
__name__
命名的模块没有全局名称,但可以作为系统所有活动模块列表sys.modules中名称为'__main__
'的模块进行访问。g = sys.modules['__main__']
,然后他们就可以访问g.whatever
。 - Andrew