如何将对象转移到python垃圾回收?

Ben*_*min 10 python garbage-collection reference

在SO中有几个关于Python垃圾收集的线程,在阅读了大约五个,加上一些文档在线后,我仍然不确定垃圾收集如何工作以及我应该如何管理我不使用的对象.事实上,我读过的某个地方不应该做任何关于收集垃圾的事情,其他人告诉一个应该是del对象,而其他人再次解释解除引用一个对象就足以让Python将其收集为垃圾.

因此,冒着创建副本的风险,我会再次提出问题,但不同的是,希望获得更全面,更清晰的信息.

在我的情况下,我想用表示人物的对象进行小模拟.Person()将创建该类的几个实例.它应该存在一段时间,直到它实际上"死",而其他实例将被创建.

现在我如何使这个Person()实例"死"(假设将创建许多这些实例,我不希望这些实例像鬼一样挂出)?

有几种方法可以引用一个对象:

john = Person('john')
Run Code Online (Sandbox Code Playgroud)

要么

people = []
people.append(Person('john'))
Run Code Online (Sandbox Code Playgroud)

要么

people = {}
people['john'] = Person('john')
Run Code Online (Sandbox Code Playgroud)

保持程序清洁,最佳地释放资源的最佳方法是什么?那么引用我的对象以便控制删除对象的最佳方法是什么?

mou*_*uad 9

也许这也可以帮助:

>>> # Create a simple object with a verbose __del__ to track gc.
>>> class C:
...     def __del__(self):
...         print "delete object"
... 
>>> c = C()
>>> # Delete the object c successfully.
>>> del c
delete object
>>> # Deletion of an object when it go out of the scope where it was defined.
>>> def f():
...     c = C()
...
>>> f()
delete object
>>> c = C()
>>> # Create another reference of the object.
>>> b = c
>>> # The object wasn't destructed the call of del only decremented the object reference. 
>>> del c
>>> # Now the reference counter of the object reach 0 so the __del__ was called. 
>>> del b
delete object
>>> # Create now a list that hold all the objects.
>>> l = [C(), C()]
>>> del l
delete object
delete object
>>> # Create an object that have a cyclic reference.
>>> class C:
...     def __init__(self):
...         self.x = self
...     def __del__(self):
...         print "delete object"
... 
>>> c = C()
>>> # Run the garbage collector to collect object.
>>> gc.collect()
9
>>> # the gc.garbage contain object that the gc found unreachable and could not be freed.  
>>> gc.garbage
[<__main__.C instance at 0x7ff588d84368>]
>>> # Break the cyclic reference.
>>> c.x = None
>>> # And now we can collect this object.
>>> del c
delete object
>>> # Create another object with cyclic reference.
>>> c = C()
>>> # When closing the interactive python interpreter the object will be collected.
delete object
Run Code Online (Sandbox Code Playgroud)

参考:del方法 ; gc模块 ; weakref模块


Dan*_*man 8

这些都与垃圾收集无关.

Python的主要内存管理方法使用引用计数.

在上面的所有情况中,Python都会保留对该对象的所有引用的计数,当没有剩余时,该对象将被删除(类似于std::shared_pointerC++).

参考文献得到下降

  1. 持有它们的对象要么被明确删除(通过del)
  2. 或者超出范围(另见这里(特别是8)).

在您的情况下,这适用于john对象或任一容people器.它们在创建它们的函数结束时超出范围(假设它们不是return对调用函数的编辑).绝大多数情况下,你可以让它们超出范围 - 只有当你创建非常重的对象或集合时 - 比如在一个大循环中 - 你可能想要明确使用它del.

垃圾收集实际上只有在存在引用周期时才会发挥作用 - 例如,当一个对象引用自身时.喜欢:

a = []
a.append(a)
Run Code Online (Sandbox Code Playgroud)

同样,这会自动发生,您不需要做任何特别的事情.


qua*_*ana 7

我发现大多数程序很自然地创建和处理对象,所以我通常从不担心它。

一些例子:

person = Person('john')
person = Person('james')
# Whoops! 'john' has died!

people = []
people.append(Person('john'))
# ...
# All 'Persons' live in people
people = []
# Now all 'Persons' are dead (including the list that referenced them)

class House():
    def setOwner(self, person):
        self.owner = person

house.setOwner(people[0])
# Now a House refers to a Person
people = []
# Now all 'Persons' are dead, except the one that house.owner refers to.
Run Code Online (Sandbox Code Playgroud)

我假设你所追求的是:

people = {}
people['john'] = Person('john')

def removePerson(personName):
    del people[personName]

removePerson('john')
Run Code Online (Sandbox Code Playgroud)

在这种情况下people是主列表,您可以控制何时Person从列表(它的字典)中添加和删除。

您可能必须彻底考虑一个人被创造然后死亡的概念:一旦被创造,这个人首先如何与模拟互动。死后,你应该如何解开引用?(一个人可以引用其他东西,就像House在我的例子中那样可以让一个人活着。你可以让其他对象只保留这个人的名字)。