2017-01-06 4 views
0

После проверки много раз, я нашел непоследовательную информацию о теме.Python __del__ не работает как деструктор?

В некотором случае я обнаружил, что __init__ and __del__ являются эквивалентом питона для конструкторов и деструкторов. Это похоже на __init__, так как я вижу, что он называется при создании класса; но __del__ никогда не вызывается, когда программа заканчивается.

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

Теперь проблема: что это? Поскольку использование класса unittest.TestCase, когда я вызываю __del__, он никогда не вызывается. К сожалению, я не могу использовать разрыв, потому что мне нужно начать процесс до того, как начнутся тесты, и закончить его, как только я закончил с тестами

+0

@DYZ CPython использует подсчет ссылок, а не сбор мусора, поэтому вы можете вообще рассчитывать на то, что освобождается после того, как всякая ссылка на него ушла. Другие версии Python могут работать по-разному, конечно. –

+0

@MarkRansom Да, вы правы. – DyZ

+0

Что вы подразумеваете под «когда я называю' __del__' он никогда не назовешь »? Как вы это называете? Этот метод (как и любой другой метод, имя которого начинается с '__'), никогда не следует вызывать вручную. Он вызывается автоматически при исчезновении всех ссылок на объект. В частности, когда вы выполняете оператор 'del'. – DyZ

ответ

3

Есть несколько сообщений SO, в которых вы видите такое поведение, а именно например, что __del__ не вызван, рассматривается. Для того, чтобы назвать несколько источников, которые я нашел интересным, и так, и в __del__ документации:
What is the __del__ method, How to call it?
I don't understand this python __del__ behaviour
https://docs.python.org/3/reference/datamodel.html#object.del

я нашел особенно освещая раздел из документации:

Примечание: del x Безразлично Прямой вызов x.__del__() - первый уменьшает счетчик ссылок для x на единицу, а последний вызывается только тогда, когда счетчик ссылок x достигает нуля. Некоторые распространенные ситуации, которые могут препятствовать отправке ссылочного счета объекта нулю, включают в себя: круглые ссылки между объектами (например, двусвязный список или древовидная структура данных с родительскими и дочерними указателями); ссылка на объект в стеке стека функции, которая поймала исключение (трассировка, хранящаяся в sys.exc_info() 2, сохраняет фрейм стека); или ссылка на объект на фрейме стека, который вызвал необработанное исключение в интерактивном режиме (трассировка, хранящаяся в sys.last_traceback, поддерживает фрейм стека). Первая ситуация может быть устранена только путем явного нарушения циклов; вторая может быть решена путем освобождения ссылки на объект трассировки, когда она больше не полезна, а третья может быть решена путем сохранения None в sys.last_traceback. Циркулярные ссылки, которые являются мусором, обнаруживаются и очищаются, когда включен циклический сборщик мусора (он включен по умолчанию). Для получения дополнительной информации об этом разделе обратитесь к документации модуля gc.

Так что, очевидно, случаи, в которых __del__ не могли бы назвать, потому что счетчик ссылок объекта не достигает нуля, а в примечании несколько случаев, перечисленных в которых такая ситуация может случиться.

+0

Часть, относящаяся к счетчику ссылок, действительно интересна; спасибо за ссылки –

Смежные вопросы