引入del关键字后解释行为的变化

问题描述 投票:1回答:2

我写了以下玩具:

def foo():
    x = 5
    def foo2():
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
        print("CP 1")
        print("x =", x)
        print("CP 2")
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
    foo2()

foo()

print("-----------------------")

def foo():
    x = 5
    def foo2():
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
        print("CP 1")
        print("x =", x)
        print("CP 2")
        del x
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
    foo2()

foo()

将产生以下输出:

Locals:  {'x': 5}
Vars:  {'x': 5}
dir:  ['x']
CP 1
x = 5
CP 2
Locals:  {'x': 5}
Vars:  {'x': 5}
dir:  ['x']
-----------------------
Locals:  {}
Vars:  {}
dir:  []
CP 1
Traceback (most recent call last):
  File "testing.py", line 34, in <module>
    foo()
  File "testing.py", line 32, in foo
    foo2()
  File "testing.py", line 26, in foo2
    print("x =", x)
UnboundLocalError: local variable 'x' referenced before assignment
>>> 

请注意,即使在两个版本相同的代码区域内,第二版的行为也要进行修改(因此应该产生相同的结果)。根据第一版,由于x确实存在于本地名称空间中,因此del语句不应该成为问题。

问题:

1)第一版或第二版是否正确? x是否应该存在于命名空间中?

2)对此行为有解释还是错误?

(遵循2:3)第二版应该没有错误运行还是应该崩溃?]

python-3.x interpreter
2个回答
1
投票

del x触发解释器隐藏在x框架之外定义的非本地foo2()变量。

如果在相同位置用del x替换x = ...,将获得相同的效果。

原因是x实际上与foo2()处于同一级别,并且在del x期间到达foo2()时,解释器决定不为本地变量保留名称x x,因此它不会使用外部名称更新您的locals()。在x中移动foo2()分配将使x成为真正的local,因此出现在locals()中:

def foo():
    def foo2():
        x = 5
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
        print("CP 1")
        print("x =", x)
        print("CP 2")
        del x
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
    foo2()

foo()
Locals:  {'x': 5}
Vars:  {'x': 5}
dir:  ['x']
CP 1
x = 5
CP 2
Locals:  {}
Vars:  {}
dir:  []

以及声明x明确引用nonlocal内部的foo2()变量:

def foo():
    x = 5
    def foo2():
        nonlocal x
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
        print("CP 1")
        print("x =", x)
        print("CP 2")
        del x
        print("Locals: ", locals())
        print("Vars: ", vars())
        print("dir: ", dir())
    foo2()

foo()
Locals:  {'x': 5}
Vars:  {'x': 5}
dir:  ['x']
CP 1
x = 5
CP 2
Locals:  {}
Vars:  {}
dir:  []

1
投票

以下帖子为我解决了它:

https://amir.rachum.com/blog/2013/07/09/python-common-newbie-mistakes-part-2/

我想突出显示:

“第一个误解是Python是一种解释型语言(很棒,我认为我们都可以同意),是逐行执行的。实际上,Python是按语句执行的。理解我的意思后,转到您喜欢的shell(我希望您没有使用默认的shell),然后键入以下内容:

def foo():

按Enter。如您所见,shell没有提供任何输出,显然正在等待您继续执行功能定义。“

这是我困惑的根源。

感谢@ norok2,将我引到这篇文章中。

([https://docs.python.org/3.1/faq/programming.html?highlight=nonlocal#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value

也有帮助)

© www.soinside.com 2019 - 2024. All rights reserved.