Python对象删除自身

61 python memory-management instance

为什么这不起作用?我正试图让一个类的实例删除自己.

>>> class A():
    def kill(self):
        del self


>>> a = A()
>>> a.kill()
>>> a
<__main__.A instance at 0x01F23170>
Run Code Online (Sandbox Code Playgroud)

Jer*_*ten 68

'self'只是对象的引用.'del self'正在从kill函数的本地命名空间中删除'self'引用,而不是实际的对象.

要自己查看,请查看执行这两​​个函数时会发生什么:

>>> class A():
...     def kill_a(self):
...         print self
...         del self
...     def kill_b(self):
...         del self
...         print self
... 
>>> a = A()
>>> b = A()
>>> a.kill_a()
<__main__.A instance at 0xb771250c>
>>> b.kill_b()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in kill_b
UnboundLocalError: local variable 'self' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法设计一个方法,使实例删除自己,或调用一个全局函数来删除它? (6认同)

Ned*_*der 42

您不需要首先使用del来删除实例.一旦对象的最后一次引用消失,该对象将被垃圾收集.也许你应该告诉我们更多有关完整问题的信息.

  • @Zen在Python中没有办法删除实例.您所能做的就是删除对实例的引用,一旦它们全部消失,就会回收该对象. (3认同)
  • @Zen你必须很好地理解你的程序,以了解你的对象是什么.你为什么要删除一个对象?你为什么关心它,当它不再被使用时它会自行消失. (2认同)

les*_*les 16

我想我终于明白了!
注意:您不应该在普通代码中使用它,但它是可能的.这仅仅是一种好奇心,请参阅此问题的实际解决方案的其他答案.


看看这段代码:

# NOTE: This is Python 3 code, it should work with python 2, but I haven't tested it.
import weakref

class InsaneClass(object):
    _alive = []
    def __new__(cls):
        self = super().__new__(cls)
        InsaneClass._alive.append(self)

        return weakref.proxy(self)

    def commit_suicide(self):
        self._alive.remove(self)

instance = InsaneClass()
instance.commit_suicide()
print(instance)

# Raises Error: ReferenceError: weakly-referenced object no longer exists
Run Code Online (Sandbox Code Playgroud)

__new__方法中创建对象时,实例将替换为弱引用代理,并且只有强引用保留在_alive类属性中.

什么是弱参考?

弱引用是一个引用,当垃圾收集器收集对象时,它不计入引用.考虑这个例子:

>>> class Test(): pass

>>> a = Test()
>>> b = Test()

>>> c = a
>>> d = weakref.proxy(b)
>>> d
<weakproxy at 0x10671ae58 to Test at 0x10670f4e0> 
# The weak reference points to the Test() object

>>> del a
>>> c
<__main__.Test object at 0x10670f390> # c still exists

>>> del b
>>> d
<weakproxy at 0x10671ab38 to NoneType at 0x1002050d0> 
# d is now only a weak-reference to None. The Test() instance was garbage-collected
Run Code Online (Sandbox Code Playgroud)

因此,对实例的唯一强引用存储在_alive类属性中.当commit_suicide()方法删除引用时,实例被垃圾收集.


S.L*_*ott 13

在这个特定的上下文中,您的示例没有多大意义.

当一个人拿起物品时,该物品保留个人存在.它并没有消失,因为它被拾起了.它仍然存在,但它(a)与存在位于同一位置,并且(b)不再有资格被接收.虽然它有状态变化,但它仍然存在.

存在和物品之间存在双向关联.存在集合中的物品.该物品与存在相关联.

当物品被存在拾取时,必须发生两件事.

  • 存在如何在一些项目中添加set项目.bag例如,您的属性可能就是这样set.[A list是一个糟糕的选择 - 袋子里有订单吗?]

  • 物品的位置从以前的位置变为存在的位置.可能有两个类os项目 - 那些具有独立位置感(因为它们自己移动)的项目和必须将位置委托给他们所在的存在或地点的项目.

在任何情况下都不需要删除任何Python对象.如果一件物品被"摧毁",那么它就不在一个存在的包里.它不在某个地方.

player.bag.remove(cat)
Run Code Online (Sandbox Code Playgroud)

是不是需要让猫从袋子里出来.由于cat不会在其他地方使用,因此它将作为"已使用"的内存存在而不存在,因为程序中的任何内容都无法访问它.当一些量子事件发生并且内存引用被垃圾收集时,它将从内存中悄然消失.

另一方面,

here.add( cat )
player.bag.remove(cat)
Run Code Online (Sandbox Code Playgroud)

将猫放在当前位置.猫继续存在,不会被垃圾熄灭.

  • 薛定谔的猫活着!或者不!那令人讨厌的哥本哈根解释令人困惑.所以是垃圾收集. (2认同)

Zac*_*aus 6

实际上,您不应该需要删除对象来执行您要执行的操作。相反,您可以更改对象的状态。无需进入编码就如何工作的一个示例是您的玩家与怪物战斗并杀死怪物。这个怪物的状态是战斗。怪物将使用战斗所需的所有方法。当怪物因为他的生命值降到 0 而死亡时,怪物状态会变成死亡,你的角色会自动停止攻击。这种方法与使用标志甚至关键字非常相似。

同样显然在 python 中删除类不是必需的,因为它们将在不再使用时自动被垃圾收集。