【问题标题】:Delete class instance from memory从内存中删除类实例
【发布时间】:2018-12-11 17:08:45
【问题描述】:

在我的程序中,我创建了无穷无尽的类实例。数量取决于程序运行的时间。但是,在运行某个代码之后,我根本不需要这些实例。我怎样才能将它们完全从内存中删除?

简单示例代码:

class Player:
    def __init__(self, color):
        self.color = color

for n in range(1000):
    p = Player('black')

del p 在这种情况下会完全删除该实例吗?

【问题讨论】:

  • 没有引用的对象会被垃圾回收器回收

标签: python python-3.x class memory instance


【解决方案1】:

当不再引用它们时,Python 会为您从内存中删除它们。如果您有引用其他 Player 实例的 Player 实例(例如:p.teammates = [list of Players]),您最终可能会得到循环引用,这可能会阻止它们被垃圾收集。在这种情况下,您应该考虑使用weakref 模块。

例如:

>>>sam = Player('blue')
>>>rob = Player('green')
>>>sam.team = [sam, rob]
>>>rob.team = [sam, rob]
>>> #sam and rob may not be deleted because they contain 
>>> #references to eachother so the reference count cannot reach 0
>>>del sam #del is a way to manually dereference an object in an interactive prompt. Otherwise the interpreter cannot know you won't use it again unlike when the entire code is known at the beginning.
>>>print(rob.team[0].color) #this prints 'blue' proving that sam hasn't been deleted yet
blue

那么我们该如何解决呢?

>>>sam = Player('blue')
>>>rob = Player('green')
>>>sam.team = [weakref.ref(sam), weakref.ref(rob)]
>>>rob.team = [weakref.ref(sam), weakref.ref(rob)]
>>> #now sam and rob can be deleted, but we've changed the contents of `p.team` a bit:
>>> #if they both still exist:
>>>rob.team[0]() is sam #calling a `ref` object returns the object it refers to if it still exists
True
>>>del sam
>>>rob.team[0]() #calling a `ref` object that has been deleted returns `None`
None
>>>rob.team[0]().color #sam no longer exists so we can't get his color
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'color'

【讨论】:

  • 如果我使用实例的属性作为创建另一个实例的参数怎么办?这会导致您正在谈论的循环引用吗?即b = Player(p.color)
  • @BasVelden p.color 将引用您在创建 p 时创建的字符串对象。如果多个Player 实例引用同一个字符串,则该字符串不会被删除,直到所有引用它的Player 实例都被删除。虽然这个概念是跨数据类型进行的(如果 color 是一个列表,那么内存中只会存在一个列表,并且对它有多个引用),特别是字符串有一个特殊的附加机制,称为string interning,以帮助减少内存使用和复制。
【解决方案2】:

在这种情况下,del p 只会删除对Player 对象的引用,以便稍后可以被垃圾收集器拾取。

但是,当它超出范围时也会发生这种情况。

在大多数日常 Python 中,不需要使用显式的 del 语句。

【讨论】:

    【解决方案3】:

    在 Python 中无法删除实例。相反,您可以删除对实例的引用,一旦它们全部消失,对象就会被回收。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      • 2016-01-21
      • 2015-05-16
      • 2016-03-14
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      相关资源
      最近更新 更多