尝试运行代码时出现的错误是:
UnboundLocalError: local variable 'a' referenced before assignment
……从表面上看,它看起来很奇怪:毕竟,上面代码中的第一个语句(a = 15)是一个赋值.发生什么了?
实际上,发生了两件截然不同的事情,除非你已经了解它们,否则它们都不明显.
首先,您实际上有两个不同的变量:
>第一行中的a是一个全局变量(因为它存在于全局范围内,在任何函数定义之外).
>其他行中的a是局部变量,这意味着它只存在于test()函数中.
这两个变量彼此完全无关,即使它们具有相同的名称.
变量是函数的局部变量,如果在该函数中有一个语句分配给它 – 例如,你的a = a 10行.
即便如此,错误仍然看起来很奇怪 – 毕竟,你在test()中做的第一件事是分配给a,那么如何才能事先引用呢?
答案是,在赋值语句中,Python会在将符号分配到左侧的名称之前评估=符号右侧的所有内容 – 因此,即使首先在代码中编写赋值,也会首先引用在那个右手边:一个10.
有两种方法可以解决这个问题.第一个是告诉Python你真的希望内部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
……一个没改变!那是因为虽然你把它传递给了test()并且它被分配给了x,然后它被改变了x,原来只留下了一个.
如果您想要实际更改a,则需要从函数返回修改后的x,然后将其重新分配给外部:
>>> a = 15
>>>
>>> def test(x):
... x = x + 10
... print(x)
... return x
...
>>> a = test(a)
25
>>> a
25