UnboundLocalError 与 python 中的运算符和函数式编程(方法工作正常)

发布于 2024-11-03 01:42:19 字数 815 浏览 0 评论 0原文

prog1.py:

def runf(f):
    f()

def main():
    l = [0]
    def f():
        l.append(1)
    runf(f)
    print(l)

main()

给我(如预期):

[0, 1]

prog2.py:

def runf(f):
    f()

def main():
    l = [0]
    def f():
        l += [1] # <-- Only difference
    runf(f)
    print(l)

main()

给我:

Traceback (most recent call last):
  File "prog2.py", line 11, in <module>
    main()
  File "prog2.py", line 8, in main
    runf(f)
  File "prog2.py", line 2, in runf
    f()
  File "prog2.py", line 7, in f
    l += [1]
UnboundLocalError: local variable 'l' referenced before assignment

有人可以向我解释一下这里发生了什么吗?

注意:在 python2 和 python3 中都会发生这种情况。

另外,我愿意接受有关该问题更好标题的建议。

prog1.py:

def runf(f):
    f()

def main():
    l = [0]
    def f():
        l.append(1)
    runf(f)
    print(l)

main()

Gives me (as expected):

[0, 1]

prog2.py:

def runf(f):
    f()

def main():
    l = [0]
    def f():
        l += [1] # <-- Only difference
    runf(f)
    print(l)

main()

Gives me:

Traceback (most recent call last):
  File "prog2.py", line 11, in <module>
    main()
  File "prog2.py", line 8, in main
    runf(f)
  File "prog2.py", line 2, in runf
    f()
  File "prog2.py", line 7, in f
    l += [1]
UnboundLocalError: local variable 'l' referenced before assignment

Could someone please explain to me what's going on here?

Note: This happens in both python2 and python3.

Also, I'm open to suggestions on a better title for this question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无妨# 2024-11-10 01:42:19

Python 的执行模型参考(第 4.1 节)指出:

如果一个名字绑定在一个块中,那么它就是一个
该块的局部变量。

发生的情况是 l += [1],出于绑定的目的,相当于 l = l + [1],这意味着 l 绑定f内。这是另一个有趣的文档参考

将对象分配给单个目标的递归定义如下。

如果目标是标识符(名称):

  • 如果该名称未出现在当前代码的全局语句中
    block:名称与对象绑定
    在当前本地命名空间中。
  • 否则:名称绑定到当前全局中的对象
    命名空间。

otherwise 子句在这里是相关的。由于您没有在 f 范围内声明 global l 并分配给 l,因此该名称绑定在 的本地命名空间中f。然后,l += [1] 隐式创建的对它的引用引用了一个尚未定义的变量。因此出现了UnboundLocalError


顺便说一句,PS global l 不会帮助你。 Python 3 有 nonlocal 语句来处理这样的情况:

非本地语句导致
列出的标识符以供参考
先前绑定的变量
最近的封闭范围。这是
很重要,因为默认行为
绑定就是搜索本地
首先命名空间。该声明允许
重新绑定变量的封装代码
除了本地范围之外
全局(模块)范围。

The execution model reference of Python (section 4.1) states:

If a name is bound in a block, it is a
local variable of that block.

What happens is that l += [1], for the sake of binding is equivalent to l = l + [1] which means l is bound inside f. Here's another interesting document reference:

Assignment of an object to a single target is recursively defined as follows.

If the target is an identifier (name):

  • If the name does not occur in a global statement in the current code
    block: the name is bound to the object
    in the current local namespace.
  • Otherwise: the name is bound to the object in the current global
    namespace.

The otherwise clause is relevant here. Since you did not declare global l in the scope of f and assigned to l, the name is bound in the local namespace of f. Then, the reference to it implicitly created by l += [1] refers to a variable that hasn't been defined yet. Hence the UnboundLocalError.


P.S. global l wouldn't help you, by the way. Python 3 has the nonlocal statement to handle cases like this:

The nonlocal statement causes the
listed identifiers to refer to
previously bound variables in the
nearest enclosing scope. This is
important because the default behavior
for binding is to search the local
namespace first. The statement allows
encapsulated code to rebind variables
outside of the local scope besides the
global (module) scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文