小编典典

尝试运行代码时遇到的错误是:

UnboundLocalError: local variable 'a' referenced before assignment

…从表面上看,这似乎很奇怪:毕竟,()代码中的第一个语句a = 15是一个赋值。发生什么了?

实际上,发生了两种截然不同的事情,除非你已经知道它们,否则它们都不是显而易见的。

首先,你实际上有两个不同的变量:

在a你的第一行是一个全局变量(所谓的,因为它存在于全球范围内,外的任何函数定义)。

将a在其他行是一个局部变量,也就是说,它只是你的内部存在test()功能。

尽管这两个变量具有相同的名称,但它们彼此之间完全不相关。

如果在函数内部有分配给该函数的语句(例如,你的a = a +10行),则该变量是函数的局部变量。

即使这样,错误仍然看起来很奇怪-毕竟,你在内部所做的第一件事test()就是分配给a,那么如何预先引用它呢?

答案是,在赋值语句中,Python先评估=符号右手边的所有内容,然后再将其赋给左手边的名称-因此,即使赋值是首先写在代码中的,也要先a被引用右侧:a +10。

有两种解决方法。首先是要告诉Python你真的希望a内部在全局范围内test()是相同a的:

def test():
global a
a = a + 10
print(a)

这将起作用,但这是编写程序的一种非常糟糕的方法。更改函数内部的全局变量很难真正快速地进行管理,因为你通常有很多函数,而且它们中的任何一个都无法确保另一个函数不会以他们不期望的某种方式弄乱全局变量。

更好的方法是将变量作为参数传递给函数,如下所示:

a = 15
def test(x):
x = x + 10
print(x)
test(a)

请注意,名称不必相同-你的新定义test()只是说它接受一个值,然后对其进行处理。你可以输入任何喜欢的内容-可以是a,或数字7或其他名称。实际上,如果你尝试避免在不同作用域中使用具有相同名称的变量,那么你的代码将始终易于理解。

如果你使用上面的代码,你会发现一些有趣的事情:

>>> a = 15
>>> test(a)
25
>>> a
15

…… a没有改变!这是因为,尽管你将其传递test()给x它,并被分配给,但后来还是x被更改了,而原来的文件却没有a。

如果要实际更改a,则需要x从函数返回修改后的值,然后将其重新分配回a外部:

>>> a = 15
>>>
>>> def test(x):
... x = x + 10
... print(x)
... return x
...
>>> a = test(a)
25
>>> a
25

2020-02-16