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

См. 10 подсказок относительно записи повторно используемого кода для некоторой справки.

  1. Сохраняют DRY кода. Сухой означает, "не Повторяют Себя".
  2. Заставляют класс/метод сделать всего одну вещь.
  3. модульные тесты Записи на Ваши классы И облегчают тестировать классы.
  4. Удаляют бизнес-логику или основной код далеко от любого кода платформы
  5. Попытка думать более абстрактно и использовать Интерфейсы и Абстрактные классы.
  6. Код для расширения. Запишите код, который может легко быть расширен в будущем.
  7. не пишут код, который не необходим.
  8. Попытка уменьшить связь.
  9. Быть больше Модульным
  10. код Записи как Ваш код является Внешним API

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

4 ответа

__ 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
поделиться

Я написал ответ на другой вопрос, хотя это более точный вопрос.

Как работают конструкторы и деструкторы?

Вот несколько самоуверенный ответ.

Не используйте __ del __ . Это не C ++ или язык, созданный для деструкторов. Метод __ del __ действительно должен быть убран в Python 3.x, хотя я уверен, что кто-то найдет вариант использования, который имеет смысл.Если вам нужно использовать __ del __ , помните об основных ограничениях для http://docs.python.org/reference/datamodel.html :

  • __del__ is вызывается, когда сборщик мусора собирает объекты, а не когда вы теряете последнюю ссылку на объект и не когда выполняете del object .
  • __ del __ отвечает за вызов любого __ del __ в суперклассе, хотя неясно, находится ли это в порядке разрешения методов (MRO) или просто вызывает каждый суперкласс.
  • Наличие __ del __ означает, что сборщик мусора отказывается от обнаружения и очистки любых циклических ссылок, таких как потеря последней ссылки на связанный список. Вы можете получить список игнорируемых объектов из gc.garbage. Иногда вы можете использовать слабые ссылки, чтобы полностью избежать цикла. Это время от времени обсуждается: см. http://mail.python.org/pipermail/python-ideas/2009-October/006194.html .
  • Функция __ del __ может обманывать, сохраняя ссылку на объект и останавливая сборку мусора.
  • Исключения, явно указанные в __ del __ , игнорируются.
  • __ del __ дополняет __ new __ намного больше, чем __ init __ . Это сбивает с толку. См. http://www.algorithm.co.il/blogs/programming/python-gotchas-1- del -is-not-the-противоположность- init / для объяснения и ошибок.
  • __ del __ не «любимый» ребенок в Python. Вы заметите, что sys.В документации exit () не указывается, собирается ли мусор перед выходом, и есть много странных проблем. Вызов __ del __ на глобальных объектах вызывает странные проблемы с упорядочением, например, http://bugs.python.org/issue5099 . Должен ли __ del __ вызываться, даже если __ init __ не работает? См. http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423 для получения информации о длинном потоке.

Но, с другой стороны:

  • __ del __ означает, что вы не забываете вызывать оператор закрытия. См. http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/ для получения профессиональной точки зрения __ del __ . Обычно речь идет об освобождении ctypes или какого-либо другого специального ресурса.

И моя личная причина, почему мне не нравится функция __ del __ .

  • Каждый раз, когда кто-то упоминает __ del __ , это превращается в тридцать сообщений о замешательстве.
  • В дзен Python разбиваются следующие элементы:
    • Простое лучше, чем сложное.
    • Особых случаев недостаточно, чтобы нарушать правила.
    • Ошибки никогда не должны проходить незаметно.
    • Перед лицом двусмысленности откажитесь от соблазна угадать.
    • Должен быть один - и желательно только один - очевидный способ сделать это.
    • Если реализацию трудно объяснить, это плохая идея.

Итак, найдите причину не использовать __ del __ .

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

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