【问题标题】:Why does the loop iterate after deleting the reference to the iterable?为什么删除对可迭代对象的引用后循环会迭代?
【发布时间】:2020-04-02 14:51:14
【问题描述】:

我在 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

标签: python python-3.x loops reference del


【解决方案1】:

循环实际上不适用于x;它使用iter(x) 的返回值,自身 持有与x 相同的对象的引用。删除 x 不会影响该引用。

del x 只减少x 引用的对象的引用计数,如果该引用计数达到 0,则该对象将被垃圾回收。它不会立即销毁对象。

第一次通过循环,名称x 仍被定义。不过,该名称已被del x 删除,因此在第二次 迭代中,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 不可见的引用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 2020-10-22
    • 2015-07-20
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    相关资源
    最近更新 更多