在第5版的第551页上,有一个名为thismod.py的以下文件:
var = 99
def local():
var = 0
def glob1():
global var
var+=1
def glob2():
var = 0
import thismod
thismod.var+=1
def glob3():
var = 0
import sys
glob = sys.modules['thismod']
glob.var+=1
def test():
print(var)
local(); glob1(); glob2(); glob3()
print(var)
此后在终端中按如下方式运行测试:
>>> import thismod
>>> thismod.test()
99
102
>>> thismod.var
102
使用local()函数非常合理,因为python在函数local()的局部范围内将变量设为var。但是,在使用全局变量时我迷失了。
如果执行以下功能:
def nonglobal():
var+=1
我在终端中运行此函数时收到UnboundLocalError。我目前的理解是,该函数将运行,并且首先搜索thismod.nonglobal的局部范围,然后由于无法在nonglobal()中找到对var的赋值,然后将搜索thismod.py文件的全局范围,其中它将找到值为99的thismod.var,但没有找到。但是,在终端之后立即运行thismod.var
会产生预期的值。因此,我显然不了解glob1()中的global var
声明发生了什么。
我曾希望glob2()中的var = 0
行也发生上述情况,但是,尽管glob1()的代码先于glob1()运行过,但它仅作为局部变量(对glob2()起作用)。那作业。我还以为glob2()中的import thismod
行会将var重置为99,但这是另一件事让我措手不及。如果我注释掉这一行,则下一行失败。
简而言之,尽管我已经阅读了本书的这一章,但我不知道这里的全球范围/进口是怎么回事。我觉得自己理解了有关全局变量和范围的讨论,但是这个例子表明我没有。感谢您的解释和/或进一步的阅读,可以帮助我解决问题。
谢谢。
除非使用global
关键字导入,否则全局作用域中的变量只能以只读方式在任何局部函数中使用。尝试写它们会产生错误。
使用赋值运算符=
创建与全局变量同名的局部变量,将“遮盖”全局变量(即,使全局变量无法访问,而有利于局部变量,并且它们之间没有其他连接)。
就此范围而言,算术赋值运算符(+=
,-=
,/=
等)使用怪异规则。一方面,您要分配一个变量,另一方面,它们是可变的,而全局变量是只读的。因此,除非首先通过使用global
将全局变量带入本地范围,否则您将得到一个错误。
请注意,var += 1
和var = var + 1
在这里具有不同的行为。如上所述,前者将出错。后者将使用var
的global,read-only值进行计算,然后将结果分配给隐藏全局变量的新local变量,而无需实际修改全局变量。
就glob2()
而言-名称thismod
不在名称空间(即范围)中,除非您将其import
放入名称空间中。由于thismod.var
现在是局部变量的属性,而不是全局只读变量,因此我们可以对其进行写入。只写限制实际上仅适用于同一文件中的全局变量。
glob3()
实际上执行与glob2
相同的操作,不同之处在于它引用sys
的导入模块列表,而不是使用import
关键字。 import
基本上表现出相同的行为(尽管过于简化)。