为什么循环在删除对可迭代对象的引用后进行迭代?
Why does the loop iterate after deleting the reference to the iterable?
我在 Windows 10 上使用 Python 3.8.2。
我有以下代码:
x = range(5)
for i in x:
print(i)
del x
预期输出:
0
Traceback (most recent call last):
File "C:\Users\Students\test.py", line 3, in <module>
for i in x:
NameError: name 'x' is not defined
实际输出:
0
1
Traceback (most recent call last):
File "C:\Users\Students\test.py", line 5, in <module>
del x
NameError: name 'x' is not defined
在第一次迭代中,我希望 del x
会删除 x
,以便在第二次迭代中它会给我错误,for i in x:
。
但是,它不断迭代,打印出 1
,然后在 del x
.
行给我错误
它似乎与任何可迭代对象的工作方式相同。我用字典、集合、元组和列表进行了测试。
我是不是遗漏了什么?
谁能解释一下这是怎么回事?
循环实际上并没有与 x
一起工作;它使用 iter(x)
的 return 值, 本身 持有与 x
相同对象的引用。删除 x
不会影响该引用。
del x
只会减少 x
引用的对象的引用计数,如果该引用计数达到 0,则该对象将被垃圾回收。它不会立即销毁对象。
第一次循环,名字x
仍然是定义的。但是,该名称已被 del x
删除,因此在 second 迭代中,del x
生成 NameError
.
你可以认为这个 for
循环大致等同于
x_iter = iter(x)
while True:
try:
i = next(x_iter)
except StopIteration:
del x_iter # Clean up the namespace before exiting the loop
break
print(i)
del x
(粗略地说,因为与此循环中的名称 x_iter
不同,for
循环使用的迭代器没有 Python-可见引用)。
我在 Windows 10 上使用 Python 3.8.2。
我有以下代码:
x = range(5)
for i in x:
print(i)
del x
预期输出:
0
Traceback (most recent call last):
File "C:\Users\Students\test.py", line 3, in <module>
for i in x:
NameError: name 'x' is not defined
实际输出:
0
1
Traceback (most recent call last):
File "C:\Users\Students\test.py", line 5, in <module>
del x
NameError: name 'x' is not defined
在第一次迭代中,我希望 del x
会删除 x
,以便在第二次迭代中它会给我错误,for i in x:
。
但是,它不断迭代,打印出 1
,然后在 del x
.
行给我错误
它似乎与任何可迭代对象的工作方式相同。我用字典、集合、元组和列表进行了测试。
我是不是遗漏了什么?
谁能解释一下这是怎么回事?
循环实际上并没有与 x
一起工作;它使用 iter(x)
的 return 值, 本身 持有与 x
相同对象的引用。删除 x
不会影响该引用。
del x
只会减少 x
引用的对象的引用计数,如果该引用计数达到 0,则该对象将被垃圾回收。它不会立即销毁对象。
第一次循环,名字x
仍然是定义的。但是,该名称已被 del x
删除,因此在 second 迭代中,del x
生成 NameError
.
你可以认为这个 for
循环大致等同于
x_iter = iter(x)
while True:
try:
i = next(x_iter)
except StopIteration:
del x_iter # Clean up the namespace before exiting the loop
break
print(i)
del x
(粗略地说,因为与此循环中的名称 x_iter
不同,for
循环使用的迭代器没有 Python-可见引用)。