@zhangyu756897669
2017-08-22T15:36:21.000000Z
字数 3128
阅读 545
python官方文档
范围很重要的原因有几个:
原因是Python具有不同的范围,而不仅仅是使全局变量成为一个全局变量,这样当变量被特定的函数调用中的代码修改时,该函数只能通过其参数和返回值与程序的其余部分进行交互。这缩小了可能导致错误的列表代码行。如果您的程序仅包含全局变量,并且由于将变量设置为错误值而发生错误,那么很难跟踪此错误值的设置。它可以从程序中的任何地方设置 - 您的程序可能是数百或数千行!但是,如果错误是因为本地变量的值不正确,那么只知道该函数中的代码只能设置不正确。
输入这个程序,运行它会导致错误:
def spam():
eggs = 31337
spam()
print(eggs)
如果您运行此程序,输出将如下所示:
Traceback (most recent call last):
File "C:/test3784.py", line 4, in <module>
print(eggs)
NameError: name 'eggs' is not defined
发生错误是因为egg变量仅存在于调用spam()时创建的本地作用域中。一旦程序执行从垃圾邮件返回,该本地范围将被销毁,并且不再有名为egg的变量。所以当你的程序试图运行打印(鸡蛋)时,Python会给你一个错误,表示没有定义蛋。如果你这么想,这是有道理的当程序执行在全局范围内时,不存在本地作用域,因此不能有任何局部变量。这就是为什么在全局范围内只能使用全局变量的原因。
每当调用函数时都会创建一个新的本地范围,包括当从另一个函数调用函数时。运行这个程序:
def spam():
❶ eggs = 99
❷ bacon()
❸ print(eggs)
def bacon():
ham = 101
❹ eggs = 0
❺ spam()
程序启动时,将spam()函数称为❺,并创建一个本地作用域。局部变量egg❶设置为99.然后将bacon()函数称为❷,并创建第二个本地范围。多个本地范围可以同时存在。在这个新的本地范围内,局部变量ham设置为101,并且还创建了与spam()的本地范围不同的局部变量egg,并将其设置为0。
当bacon()返回时,该调用的本地作用域被销毁。在spam()函数中继续执行程序执行以打印蛋❸的值,并且由于本地调用spam()的范围仍然存在于这里,因此将egg变量设置为99.这是程序打印的内容。
结果是,一个函数中的局部变量与另一个函数中的局部变量完全分离。
运行程序:
def spam():
print(eggs)
eggs = 42
spam()
print(eggs)
由于没有名为egg的任何参数或任何为spam()函数赋值的代码,因此当使用spam()函数时,Python将其视为对全局变量egg的引用。这就是为什么当前一个程序运行时打印42。
为了简化您的生活,请避免使用与全局变量或其他局部变量具有相同名称的局部变量。但从技术上讲,在Python中这样做是完全合法的。运行程序:
def spam():
❶ eggs = 'spam local'
print(eggs) # prints 'spam local'
def bacon():
❷ eggs = 'bacon local'
print(eggs) # prints 'bacon local'
spam()
print(eggs) # prints 'bacon local'
❸ eggs = 'global'
bacon()
print(eggs) # prints 'global'
当您运行此程序时,它输出以下内容:
bacon local
spam local
bacon local
global
如果需要从函数内修改全局变量,请使用全局语句。如果在函数顶部有一个全局蛋的行,它会告诉Python,“在这个函数中,egg是指全局变量,所以不要用这个名称创建一个局部变量”。输入以下代码:
def spam():
❶ global eggs
❷ eggs = 'spam'
eggs = 'global'
spam()
print(eggs)
当您运行此程序时,最终的print()调用将会输出:
spanm
有四个规则来判断一个变量是在一个局部作用域还是在全局范围内:
为了更好地了解这些规则,以下是一个示例程序。
def spam():
❶ global eggs
eggs = 'spam' # this is the global
def bacon():
❷ eggs = 'bacon' # this is a local
def ham():
❸ print(eggs) # this is the global
eggs = 42 # this is the global
spam()
print(eggs)
在spam()函数中,鸡蛋是全球蛋变量,因为在函数开始处有一个全球性的蛋类声明❶。在培根()中,蛋是一个局部变量,因为在该函数中有一个赋值语句❷。在ham()❸中,eggs是全局变量,因为在该函数中没有赋值语句或全局语句。运行程序,将出现以下结果:
spam
def spam():
print(eggs) # ERROR!
❶ eggs = 'spam local'
❷ eggs = 'global'
spam()
如果运行上一个程序,则会产生错误消息。
Traceback (most recent call last):
File "C:/test3784.py", line 6, in
spam()
File "C:/test3784.py", line 2, in spam
print(eggs) # ERROR!
UnboundLocalError: local variable 'eggs' referenced before assignment
发生这种错误是因为Python看到在spam()函数❶中有一个适用于蛋的赋值语句,因此认为蛋是本地的。但是,因为打印(鸡蛋)在鸡蛋被分配任何东西之前执行,所以局部变量蛋不存在。 Python不会回到使用全局的蛋变量❷。
此功能为“黑匣子”