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

问题描述:

我写了以下玩具:

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语句不应该成为问题.

Notice how behaviour of the second edition is modified even in the areas of the code up to which the two editions are identical (and thus should produce identical outcomes). Since x, according to the first edition, does exist in the local namespace, the del statement shouldn't be an issue.

问题:

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

1) Is the first or second edition 'right'? Should x exist in the namespace or not?

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

2) Is there an explanation for this behaviour or is it a bug?

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

(Follow up to 2: 3) Should the second edition run without an error or is it supposed to crash?)

以下帖子为我解决了这个问题:

The following post solved it for me:

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

我想强调:

第一个误解是Python是一种解释性语言(很棒,我想我们都同意),它是逐行执行的.实际上,Python是按语句执行的.理解我的意思,转到您喜欢的shell(我希望您没有使用默认的shell)并输入以下内容:

"The first misconception is that Python, being an interpreted language (which is awesome, I think we can all agree), is executed line-by-line. In truth, Python is being executed statement-by-statement. To get a feel of what I mean, go to your favorite shell (you aren’t using the default one, I hope) and type the following:

def foo():

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

Press Enter. As you can see, the shell didn’t offer any output and it’s clearly waiting for you to continue with your function definition."

这是我困惑的根源.

感谢@ norok2向我指出了一条指向我的帖子.

Thanks to @norok2 for pointing me to a post which pointed me to this.

(也很有帮助)