Python 3.x 引入del关键字后解释行为的变化
我写了以下玩具:Python 3.x 引入del关键字后解释行为的变化,python-3.x,interpreter,Python 3.x,Interpreter,我写了以下玩具: 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())
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':5}
变量:{'x':5}
目录:['x']
CP 1
x=5
CP 2
局部变量:{'x':5}
变量:{'x':5}
目录:['x']
-----------------------
本地人:{}
变量:{}
目录:[]
CP 1
回溯(最近一次呼叫最后一次):
文件“testing.py”,第34行,在
foo()
文件“testing.py”,第32行,在foo中
foo2()
foo2中第26行的文件“testing.py”
打印(“x=”,x)
UnboundLocalError:赋值前引用了局部变量“x”
>>>
请注意,即使在两个版本完全相同的代码区域中,第二版本的行为也会被修改(因此应该产生相同的结果)。根据第一版,由于x确实存在于本地名称空间中,因此del语句不应该成为问题
问题:
1) 第一版或第二版“正确”吗?x是否应该存在于名称空间中
2) 这种行为有什么解释吗?还是一个bug
(跟进到2:3)第二版是否运行时没有错误或应该崩溃?del x触发解释器隐藏在
foo2()
框架外定义的非本地x
变量
如果将del x
替换为x=…
位于相同位置,将获得相同的效果
原因是x
实际上与foo2()
处于同一级别,并且在foo2()
期间到达del x
时,解释器决定不为局部变量x
保留名称x
,因此它不会更新局部变量()
使用外部名称中的名称。将x
赋值移动到foo2()
中会使x
成为真正的local
,因此出现在locals()
中:
局部变量:{'x':5}
变量:{'x':5}
目录:['x']
CP 1
x=5
CP 2
本地人:{}
变量:{}
目录:[]
以及声明x
以在foo2()中显式引用非本地
变量:
局部变量:{'x':5}
变量:{'x':5}
目录:['x']
CP 1
x=5
CP 2
本地人:{}
变量:{}
目录:[]
以下帖子为我解答了这个问题:
我想强调:
“第一个误解是Python是一种解释语言(我想我们都同意这一点,它非常棒),是逐行执行的。事实上,Python是一条语句一条语句地执行的。要了解我的意思,请转到您最喜欢的shell(我希望您没有使用默认的shell)并键入以下内容:
def foo():
按Enter键。如您所见,shell没有提供任何输出,它显然在等待您继续您的函数定义。”
这就是我困惑的根源
感谢@norok2为我指出了一篇文章,这篇文章为我指明了方向
(
也很有帮助)这与观察到的范围界定行为有些相似。我不理解你的解释。为什么要在定义时执行del?如果是,则类似于>>>def g():。。。l=[1,2,3]。。。打印(l)。。。德尔l…>>>g()[1,2,3]不起作用,而且关键字也没有意义。@EdwardGaremo抱歉,解释有误导性。我现在已经改进了。我仍然不明白我的想法。我知道在foo2中指定x会影响到foo中的x,但这不应该只在相关行x=。。。还是执行delx?(我认为我对执行模型有一个误解:我认为,作为一种解释性语言,python的每一行都是一行接一行地执行的——但您的回答(以及行为)暗示了某种前瞻性)@爱德华·加雷莫(EdwardGaremo)从提议的复制品中应该为你清除潜在的机制。相关:这是否回答了你的问题?
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()
def foo():