Как отдать объект в сборку мусора python?

есть несколько потоков на сборке мусора Python в SO, и после прочтения около пяти, плюс некоторые doc в строке, я все еще не уверен, как работает сбор мусора и как я должен управлять объектами, которые я не использую. На самом деле где-то я читал, что нельзя ничего делать со сбором мусора, другие говорят, что нужно del объекты, в то время как другие снова объясняют, что де-ссылки на объект достаточно для Python, чтобы собрать его как мусор.

Итак, рискуя создать дубликат, я задам вопрос еще раз, но по-другому, надеясь получить более полную и четкую информацию.

в моем случае я хочу сделать небольшую симуляцию с объектами, представляющими людей. Несколько примеров Person() класс будет создан. Он должен существовать некоторое время, пока он практически не "умрет", а другие экземпляры будут созданы.

теперь как мне сделать этот Person() экземпляр " die "(предполагая, что многие из этих экземпляров будут созданы, и я не хотите, чтобы эти экземпляры болтались, как призраки)?

есть несколько способов, которыми я могу ссылаться на объект:

john = Person('john')

или

people = []
people.append(Person('john'))

или

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

каков наилучший способ сохранить мою программу в чистоте, оптимально освобождая ресурсы? И каков наилучший способ ссылаться на мой объект, чтобы я мог контролировать удаление объекта?

3 ответов


Я считаю, что большинство программ создают и распоряжаются объектами вполне естественно, поэтому я обычно не беспокоюсь об этом.

примеры:

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.

Я предполагаю, что вам нужно следующее:

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

def removePerson(personName):
    del people[personName]

removePerson('john')

в этом случае people является основным списком, и вы можете контролировать, когда Person добавляется и удаляется из списка (его словарь).

возможно, вам придется продумать концепцию человека, который создается, а затем умирает очень тщательно: один раз создано как человек сначала взаимодействует с симуляцией. После смерти, как вы должны распутать ссылки? (Его нормально для человека ссылаться на другие вещи, его вещи, как House в моем примере это сохранит человеку жизнь. Вы могли бы иметь другие объекты, держащиеся только за имя человека).


возможно, это также может помочь:

>>> # 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

Refrences:дель метод ; модуль gc ; модуль weakref


ничего этого на самом деле не имеет ничего общего со сборкой мусора.

основной метод управления памятью Python использует подсчет ссылок.

во всех случаях выше Python сохраняет количество всех ссылок на объект, и когда их не осталось, объект удаляется (аналогично std::shared_pointer в C++).

ссылки уменьшаются, когда

  1. объект, удерживающий их, либо явно удалил (через del)
  2. или выходит за рамки (см. Также здесь (esp. бывший. 8)).

в вашем случае, это относится к john объект, или любой из people контейнеров. Они выходят за рамки в конце функции, которая их создала (предполагая, что они не returned для вызывающей функции). В подавляющем большинстве случаев вы можете просто позволить им выйти за рамки-это только тогда, когда вы создаете действительно тяжелый объекты или коллекции-скажем, внутри большого цикла - которые вы можете явно использовать del.

вывоз мусора действительно вступает в игру только тогда, когда есть ссылочные циклы - например, когда объект ссылается на себя. Например:

a = []
a.append(a)

опять же, это происходит автоматически, и вам не нужно делать ничего особенного.