2016-01-25 3 views
0

У меня есть некоторый test.py файл:__del__ на поведение выхода

class A: 
    def __init__(self): 
     print("A init") 

    def __del__(self): 
     print("A del") 

a = A() 

Когда я запускаю его в 10 раз (python3 test.py) всегда производит следующий вывод:

A init 
A del 

Но если добавить sys.exit вызов до конца сценария:

import sys 

class A: 
    def __init__(self): 
     print("A init") 

    def __del__(self): 
     print("A del") 

a = A() 

sys.exit(-1) 

в 5 из 10 случаев (случайно) у меня есть

A init 

и во второй половине случаев:

A init 
A del  

Я использую Python3.4.3 [MSC v.1600 32 разрядную] на Windows 7 x64. Итак, почему метод __del__ называется не каждый раз? Нужно ли мне использовать какой-либо другой метод выхода для передачи кода возврата сценария и гарантированного выполнения всех деструкторов? И еще один связанный с этим вопрос: можно ли запустить деструкторы при получении SIGTERM или SIGKILL из ОС?

+5

Если вы хотите, чтобы гарантировать метод очистки вызывается, рассмотрим менеджер контекста. – jonrsharpe

+2

Вы почти никогда не должны использовать '__del__'. Вы можете поймать сигналы с помощью модуля 'signal', за исключением SIGKILL, который нельзя поймать. – L3viathan

+0

Кроме того, используйте 'sys.exit (0);', что означает, что код работал правильно. – AMACB

ответ

2

От documentation:

не гарантируется, что __del__() методы вызываются для объектов, которые все еще существуют, когда выходы интерпретатора.

Если вы хотите, чтобы убедиться, что a.__del__ вызывается, вы должны явно удалить экземпляр:

a = A() 
del a # Assuming this is the final reference to the object 
+1

Возможно, стоит отметить, что вызов 'del a' не обязательно означает, что метод' __del__' объекта вызывается. Это только * конечно *, если вы используете CPython, и нет никаких других ссылок на объект. В других ситуациях он может подвергаться прихотям сборщика мусора. – Blckknght

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