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

标签 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]

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

最佳答案

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

inner() 正在访问其父级范围内的变量(我认为这在技术上不是闭包,因为父级的执行尚未完成)。但是 inner() 只能解引用那个名字,不能赋值给它,因为 b 不是 inner() 的局部变量,也没有被声明为全局非本地

所以你可以取消引用 b 并改变它引用的列表,但你不能分配给它。当您尝试通过以 b += 开头的行来分配给它时,您是在说“像本地人一样对待 b”。在正常的 b = 3 赋值中,这实际上会成功完成,像其他任何变量一样创建一个局部变量。但在这种情况下,由于 b 在本地上下文中没有已分配的值,取消引用 b 以执行添加过程 失败。

碰巧的是,您不能一开始就简单地将一个整数添加到列表中。 +=append 不同,甚至搁置赋值与突变,因此即使您没有超出范围,它也会因 而失败类型错误b += [3] 更接近你的意思,尽管它仍然会由于变量的范围而失败。

关于python - 列表追加 VS。 += 在内部函数中获取 UnboundLocalError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23100251/

相关文章:

python - 到达边界后如何重置位置

python-2.7 - 我可以在我的机器上同时为 python 2.7 和 3.5 安装 tensorflow 吗?

python - 如何在 python 3 中从 resource_stream 加载 json

python - 如何禁用Python警告?

python - securecrt python 脚本使用特殊端口打开 ssh

python - 在 Python 3x 中对列表/元组执行计算的最佳方法

python - Django 1.9 中的 Mysql 连接问题

Python SUDS 返回类型不是 XML

Python:变长元组

python-3.x - 最新的 centos docker 图像在 yum 存储库中没有 python3