在Mark Lutz的“ Learning Python”中混淆使用global

问题描述 投票:3回答:1

在第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,但这是另一件事让我措手不及。如果我注释掉这一行,则下一行失败。

简而言之,尽管我已经阅读了本书的这一章,但我不知道这里的全球范围/进口是怎么回事。我觉得自己理解了有关全局变量和范围的讨论,但是这个例子表明我没有。感谢您的解释和/或进一步的阅读,可以帮助我解决问题。

谢谢。

python import scope global
1个回答
0
投票

除非使用global关键字导入,否则全局作用域中的变量只能以只读方式在任何局部函数中使用。尝试写它们会产生错误。

使用赋值运算符=创建与全局变量同名的局部变量,将“遮盖”全局变量(即,使全局变量无法访问,而有利于局部变量,并且它们之间没有其他连接)。

就此范围而言,算术赋值运算符(+=-=/=等)使用怪异规则。一方面,您要分配一个变量,另一方面,它们是可变的,而全局变量是只读的。因此,除非首先通过使用global将全局变量带入本地范围,否则您将得到一个错误。

请注意,var += 1var = var + 1在这里具有不同的行为。如上所述,前者将出错。后者将使用varglobal,read-only值进行计算,然后将结果分配给隐藏全局变量的新local变量,而无需实际修改全局变量。


glob2()而言-名称thismod不在名称空间(即范围)中,除非您将其import放入名称空间中。由于thismod.var现在是局部变量的属性,而不是全局只读变量,因此我们可以对其进行写入。只写限制实际上仅适用于同一文件中的全局变量。

glob3()实际上执行与glob2相同的操作,不同之处在于它引用sys的导入模块列表,而不是使用import关键字。 import基本上表现出相同的行为(尽管过于简化)。

© www.soinside.com 2019 - 2024. All rights reserved.