列表追加VS. + =在内部函数中获取UnboundLocalError

时间:2014-04-16 04:52:26

标签: python python-3.x

我跟随引发异常的代码:

def a():
     b = []
     def inner():
         b += 3
     inner()
     print (b)

>>> a()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<console>", line 6, in a
  File "<console>", line 5, in inner
UnboundLocalError: local variable 'b' referenced before assignment

但是,如果我重写这样的代码,它会按预期运行:

def a():
     b = []
     def inner():
         b.append(5)
     inner()
     print(b)

>>> a()
[5]

我想知道为什么会这样,谢谢。

2 个答案:

答案 0 :(得分:3)

两者之间的区别在于b += 3是一个赋值 - 它将一个全新的值(添加空列表的结果和3)分配给b。相反,b.append()会改变b引用的列表而不重新分配它。

inner()正在访问其父级范围内的变量(我认为这在技术上并不是一个闭包,因为父级的执行尚未完成)。但inner()只能取消引用该名称,而不能分配给该名称,因为b不是inner()的本地名称,并且未声明为globalnonlocal。< / p>

因此,您可以取消引用b并改变它引用的列表,但您无法分配它。当您尝试通过使用b +=开始分配时,您会说“将b视为本地”。在正常的b = 3赋值中,这实际上会成功完成,创建一个局部变量,就像任何其他变量一样。但在这种情况下,由于b在本地上下文中尚未分配值,因此解除引用b以执行添加过程失败。

实际上,您不能简单地将整数添加到列表中。 +=append不同,甚至将分配与变异放在一边,所以即使你没有超出范围,它也会因TypeError而失败。 b += [3]更接近你的意思,虽然由于变量的范围仍会失败。

答案 1 :(得分:2)

在这里您可以找到确切的解释。 http://eli.thegreenplace.net/2011/05/15/understanding-unboundlocalerror-in-python/

  

如果您正密切关注StackOverflow上的Python标记,那么您将会这样做   请注意,每周至少会出现一次相同的问题。

     

&LT; ..&GT;

     

虽然这个问题在Python的官方常见问题解答(right here)中得到了解答,但是我   决定写这篇文章的目的是给出更深入的解释。

     

&LT; ..&GT;

     

那么异常来自哪里?引用常见问题解答:

     
    

这是因为当您对作用域中的变量进行赋值时,     该变量变为该范围的本地变量并且影响任何变量     在外部范围内类似命名的变量。