2016-06-16 5 views
9

Я делаю вещи в основном на C++, где метод деструктора действительно предназначен для уничтожения приобретенного ресурса. Недавно я начал с python (это действительно весело и фантастично), и я пришел, чтобы узнать, что он имеет GC как java. Таким образом, нет особого акцента на владение объектами (строительство и разрушение).Является ли __del__ действительно деструктором?

Насколько я понял, метод __init__() имеет больше смысла для меня в python, чем для ruby ​​тоже, но метод __del__(), действительно ли нам нужно реализовать эту встроенную функцию в нашем классе? Будет ли у моего класса что-то недостающее, если я пропущу __del__()? Один сценарий, который я мог увидеть, полезен, если я хочу что-то регистрировать при уничтожении объекта. Есть ли что-то другое, кроме этого?

+4

Нет. Вы почти никогда не должны реализовывать '__del__'. –

+0

http://stackoverflow.com/a/2433847/2681632 –

+3

Вы * почти никогда не хотите реализовать '__del__'. Классы, которые предоставляют пользовательский '__del__', должны обрабатываться GC при работе с циклами (потому что' __del__' следует называть ровно один раз), и в некоторых случаях GC не сможет их собрать [хотя от python3.4 + это было улучшено довольно много]. Очень мало случаев, когда это хорошая идея для его реализации. – Bakuriu

ответ

10

От Python 3 docs:

object.__del__(self)

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

Так ведь это является деструктор (но вы можете назвать это явно себя в качестве метода класса).

Однако из other answers, но и от Wikipedia:

В языке с автоматическим механизмом сбора мусора, было бы трудно детерминировано обеспечить вызов деструктора, и, следовательно, эти языки, как правило, считается непригоден для RAII [Resource Acquisition Is Initialization]

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

+3

Одна из наших возможностей заключается в том, чтобы очистить критический ресурс до сбора мусора. То есть в '__del__' проверьте, нормально ли закрыт ресурс, а если нет, сделайте это и выпустите предупреждение. – doublep

1

Действительно деструктор?

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

+0

Будет ли вызов __del__ произойти, когда это произойдет или что-то вроде того, что у нас есть как finalize() в java, я слышал, что какой-то вызов finalize() непредсказуем –

+0

@Explorer_N, он всегда будет вызываться интерпретатором python, когда объект должен быть удален. – Netwave

5

Как уже указывалось в других ответах, вы, вероятно, не должны реализовывать __del__ в Python. Если вы столкнулись с ситуацией, думая, что вам действительно нужен деструктор (например, если ваш класс обертывает ресурс, который должен быть явно закрыт), то в пути Pythonic используется context managers.

+0

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

+1

@Explorer_N Нет, вам нужно будет сделать это самостоятельно. И у них также нет одинаковой семантики. Но это легко сделать. – glglgl

+1

@Explorer_N: Обычно вам необходимо реализовать функциональность самостоятельно для пользовательских классов, часто очень легко использовать помощники из модуля ['contextlib'] (https://docs.python.org/3/library/contextlib.html). –

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