为什么循环在删除对可迭代对象的引用后进行迭代?

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-可见引用)。