Что __ del __ метод, Как назвать его?

Я читаю код. Существует класс в который __del__ метод определяется. Я выяснил, что этот метод используется для уничтожения экземпляра класса. Однако я не могу найти место, где этот метод используется. Главная причина для этого состоит в том, что я не знаю, как этот метод используется, вероятно, не как этот: obj1.del(). Так, мои вопросы то, как звонить __del__ метод?

89
задан vinzee 23 July 2019 в 13:07
поделиться

3 ответа

__ del __ - финализатор . Он вызывается, когда объект собирает мусор , что происходит в какой-то момент после удаления всех ссылок на объект.

В простом случае это может быть сразу после того, как вы скажете del x или, если x - локальная переменная, после завершения функции. В частности, если нет циклических ссылок, CPython (стандартная реализация Python) немедленно выполняет сборку мусора.

Однако это деталь реализации CPython. Единственное требуемое свойство сборки мусора Python - это то, что это происходит после удаления всех ссылок, поэтому это может не происходить сразу после , а может вообще не происходить .

Более того, переменные могут существовать долгое время по многим причинам , например, распространяющееся исключение или самоанализ модуля могут поддерживать счетчик ссылок на переменную больше нуля. Кроме того, переменная может быть частью цикл ссылок - CPython с включенной сборкой мусора прерывает большинство, но не все, такие циклы, и даже то только периодически.

Поскольку у вас нет гарантии, что он выполняется, нельзя никогда ставить код, который необходимо запустить в __ del __ () - вместо этого этот код принадлежит предложению finally блока try или диспетчеру контекста в с заявлением . Однако, существуют допустимые варианты использования для __ del __ : например, если объект X ссылается на Y , а также сохраняет копию Y в глобальном кэше ( cache ['X -> Y'] = Y ), то было бы вежливо, если бы X .__ del __ также удалили запись в кэше.

Если вы знаете , что деструктор обеспечивает (в нарушение приведенного выше правила) необходимую очистку, вы можете вызвать его напрямую , поскольку в нем нет ничего особенного как метод: x .__ del __ () . Очевидно, вам следует делать это только в том случае, если вы знаете, что он не против, когда вам дважды позвонят. Или, в крайнем случае, вы можете переопределить этот метод, используя

type(x).__del__ = my_safe_cleanup_method  
142
ответ дан 24 November 2019 в 07:12
поделиться

Метод __ del __ , он будет вызываться при сборке мусора. Обратите внимание, что его вызов не обязательно гарантируется. Следующий код сам по себе не обязательно сделает это:

del obj

Причина в том, что del просто уменьшает счетчик ссылок на единицу. Если что-то еще имеет ссылку на объект, __ del __ не будет вызван.

Однако есть несколько предостережений при использовании __ del __ . Как правило, они обычно не очень полезны. Для меня это больше похоже на то, что вы хотите использовать метод close или, может быть, с оператором .

См. документацию python в __ del __ методах .

Еще одно замечание: методы __ del __ могут препятствовать сборке мусора при чрезмерном использовании. В частности, циклическая ссылка, которая имеет более одного объекта с методом __ del __ , не будет собираться сборщиком мусора. Это потому, что сборщик мусора не знает, какой из них вызвать первым. Дополнительную информацию см. В документации по модулю gc .

12
ответ дан 24 November 2019 в 07:12
поделиться

Метод __ del __ (обратите внимание на правописание!) вызывается, когда ваш объект окончательно уничтожается. С технической точки зрения (в cPython), когда на ваш объект больше нет ссылок, т.е. когда он выходит за пределы области видимости.

Если вы хотите удалить свой объект и, таким образом, вызвать метод __ del __ , используйте

del obj1

, который удалит объект (при условии, что на него не было других ссылок).

Я предлагаю вам написать небольшой класс вроде этого

class T:
    def __del__(self):
        print "deleted"

И исследовать его в интерпретаторе python, например

>>> a = T()
>>> del a
deleted
>>> a = T()
>>> b = a
>>> del b
>>> del a
deleted
>>> def fn():
...     a = T()
...     print "exiting fn"
...
>>> fn()
exiting fn
deleted
>>>   

Обратите внимание, что jython и ironpython имеют разные правила относительно того, когда именно удаляется объект и __ del __ называется. Использование __ del __ не считается хорошей практикой, хотя из-за этого и того факта, что объект и его окружение могут находиться в неизвестном состоянии при его вызове. Абсолютно не гарантируется, что __ del __ также будет вызван - интерпретатор может выйти разными способами без удаления всех объектов.

Считается хорошей практикой использовать __ del __ , хотя из-за этого и того факта, что объект и его окружение могут находиться в неизвестном состоянии при его вызове. Абсолютно не гарантируется, что __ del __ также будет вызван - интерпретатор может выйти разными способами без удаления всех объектов.

Считается хорошей практикой использовать __ del __ , хотя из-за этого и того факта, что объект и его окружение могут находиться в неизвестном состоянии при его вызове. Абсолютно не гарантируется, что __ del __ также будет вызван - интерпретатор может выйти разными способами без удаления всех объектов.

8
ответ дан 24 November 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: