Python中del运算符的行为

时间:2013-11-25 02:10:05

标签: python garbage-collection destroy reference-counting del

我想知道以下为什么不起作用。

class Node(object):
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

    def remove(self, value):
        if self is None:
            return False
        if self.data == value:
            if self.next:
                self.data = self.next.data
                self.next = self.next.next
            else:
                del self
        else:
            self.next.remove(value)

    node = Node(4)
    node.append(Node(3))
    node.remove(3)
    print node.next.data
    #prints 3

del不会从链接列表中删除该元素。我必须修改delete()函数,以便我有一个指向目标元素父级的指针。

class Node(object):
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

    def remove(self, value):
        if self is None:
            return False
        if self.data == value:
            if self.next:
                self.data = self.next.data
                self.next = self.next.next
            else:
                del self
        else:
            current = self
            while current.next:
                if current.next.data == value:
                    if current.next.next:
                        current.next = current.next.next
                    else:
                        current.next = None

从控制台

node = Node(4)
current = node
del current #node is not deleted because I am only deleting the pointer
del node #node is deleted

这对我来说似乎合乎逻辑。但是,我不确定为什么第一个代码块不能像我期望的那样工作。

1 个答案:

答案 0 :(得分:1)

我会解释为什么它不起作用。但首先你需要知道你很少需要在Python中创建链表,因为列表类型已经为你提供了几乎所有东西。

>>> [2*i for i in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> list_1=[2*i for i in range(10)]
>>> i=0
>>> list_1[i]#first
0
>>> i=i+1
>>> list_1[i]#next
2
>>> list_1[-1]#last
18
>>> len(list_1)#size
10
>>> del list_1[-1]# del the last
#delete all (list_1 becomes empty)
for i in range(len(list_1)):
    del list_1[0]

在结束循环中我们只删除前n次,但是当你在列表中第一个删除时,另一个对象又回到1位。这样你就可以轻松地操作列表,好像它们是链接列表并删除任何元素而不用担心关于一个空槽。除此之外,list还有几个非常有用的方法,如append,remove,sort,shuffle等。查看文档https://docs.python.org/3.5/library/stdtypes.html?highlight=list#list

现在回到你的问题: 我们来看看你的删除方法

if self is None:
    return False

这没用,只能使用具有此方法的对象调用.remove。 None.remove()永远不会奏效。如果self为None,则会在任何(不可能的)调用之前抛出错误。

else:
    del self

当你在Object的方法中看到self时,它只是对象本身的引用,del sel将只删除本地引用。如果你真的想要销毁一个对象,你必须在每个引用上使用del来销毁它。如果没有生命变量正在查看它,Python会忘记你的对象。您也可以覆盖参考。

>>> node = Node(4)
>>> node = 3# the Node object is erased because you can t have access to it

总的来说,除了创建链表之外,我并没有真正理解你的Node类的目标,但正如我所说,你可以用list()来做到这一点。通常,您不需要关心Python中删除的内容,因为如果没有对象的引用,Python将覆盖内存。