【问题标题】:Why doesn't del do the same thing?为什么 del 不做同样的事情?
【发布时间】:2014-06-16 03:32:26
【问题描述】:

为什么下面的代码会改变这两个变量:

>>> a = []
>>> b = a
>>> a.append(9)
>>> a
[9]
>>> b
[9]
>>> 

但是del语句没有达到同样的效果?

>>> a = []
>>> b = a
>>> del(a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
[]
>>> 

【问题讨论】:

  • 请不要在不知道 del 做什么的情况下,继续使用您编写的标签 wiki 创建 python-del 标签。它不会删除对象,也不需要以新标签开头。

标签: python append del


【解决方案1】:

当你这样做时:

a = b

您所做的是将标签 b 分配给标签 a 所指的同一对象。

当你这样做时:

a.append(9)

您将9 添加到ab 指向的列表对象。这是同一个对象,所以它们显示相同的结果。

当你这样做时:

del a

您删除的是对象的引用,而不是对象本身。如果它是 only 引用,那么该对象将被垃圾回收。但在您的情况下,还有另一个参考 - b - 所以该对象继续存在。

【讨论】:

    【解决方案2】:

    考虑名称和对象,而不是“变量”。

    >>> a = []
    

    这会创建一个空列表对象并将名称 a 绑定到它。

    >>> b = a
    

    这只是说b 现在是a 命名的对象的新名称。我们有

    >>> a is b
    True
    

    del a 表示我们忘记了名称a:它不再绑定到对象。

    >>> del a
    >>> a
    Traceback (most recent call last):
      File "<ipython-input-8-60b725f10c9c>", line 1, in <module>
        a
    NameError: name 'a' is not defined
    

    但是您不再调用该列表对象a,仅调用b,不会以任何方式影响对象本身。对象不关心,甚至不知道你给它们起什么名字。 [一个半例外是,如果一个对象不再有任何引用,它可能——也可能不是,没有承诺——被垃圾收集。]

    【讨论】:

      【解决方案3】:

      append 方法作用于实际对象,而del 作用于引用,即变量名。

      【讨论】:

        【解决方案4】:

        (我已经在the other question of yours回答了这个问题,所以我也打算在这里使用它,稍作修改:)

        del 不删除对象;事实上,在 Python 中,甚至不可能告诉解释器/VM 从内存中删除对象,因为 Python 是一种垃圾收集语言(如 Java、C#、Ruby、Haskell 等)。

        相反,del 在这样的变量(而不是字典键或列表项)上调用时会做什么:

        del a
        

        是它删除局部(或全局)变量它指向的(Python中的每个变量都持有指向其内容的指针/引用而不是内容本身)。事实上,由于局部变量和全局变量在底层存储为字典(参见locals()globals()),del a 相当于:

        del locals()['a']
        

        (或 del globals()['a'] 应用于全局。)

        如果你有:

        a = []
        b = a
        

        您正在制作一个列表,将对其的引用存储在 a 中,然后将该引用复制到 b 中,而无需复制/触摸列表对象本身。因此这两个调用影响同一个对象:

        >>> a.append(1)
        >>> b.append(2)
        >>> a
        [1, 2]
        >>> b
        [1, 2]
        >>> a is b  # would be False for 2 identical but different list objects
        True
        >>> id(a) == id(b)
        True
        

        (id返回一个对象的内存地址)

        而删除b 与触摸b 指向的内容没有任何关系:

        >>> a = []
        >>> b = a
        >>> del b  # a is still untouched and points to a list
        >>> b
        NameError: name 'b' is not defined
        >>> a
        []
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-10-24
          • 2017-03-06
          • 2014-08-27
          • 2019-12-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多