2016-06-16 14 views
9

Ich mache Dinge meist in C++, wo die Destruktor-Methode wirklich für die Zerstörung einer erworbenen Ressource gedacht ist. Vor kurzem begann ich mit Python (was wirklich ein Spaß und fantastisch ist), und ich kam zu lernen, es hat GC wie Java. Daher gibt es keine starke Betonung auf Objektbesitz (Konstruktion und Zerstörung).Ist __del__ wirklich ein Destruktor?

Soweit ich gelernt habe, die __init__() Methode mehr Sinn für mich in Python macht, als es auch für Ruby tut, aber die __del__() Methode, brauchen wir implementieren diese integrierte Funktion in unserer Klasse wirklich? Wird meiner Klasse etwas fehlen, wenn ich __del__() vermisse? Das eine Szenario, das ich sehen konnte __del__() nützlich ist, wenn ich etwas beim Löschen eines Objekts protokollieren möchte. Gibt es etwas anderes als das?

+4

Nein. Sie sollten fast nie '__del__' implementieren. –

+0

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

+3

Sie * fast nie * möchten "__del__" implementieren. Klassen, die ein benutzerdefiniertes '__del__' bereitstellen, müssen vom GC auf besondere Weise behandelt werden, wenn es um Zyklen geht (weil' __del__' genau einmal aufgerufen werden muss) und in einigen Fällen kann der GC sie nicht sammeln von python3.4 + das wurde ziemlich verbessert]. Es gibt nur sehr wenige Fälle, in denen eine Implementierung sinnvoll ist. – Bakuriu

Antwort

10

Vom Python 3 docs:

object.__del__(self)

aufgerufen, wenn die Instanz zu vernichten. Dies wird auch als Destruktor bezeichnet. Wenn eine Basisklasse über eine __del__()-Methode verfügt, muss die Methode __del__() der abgeleiteten Klasse (sofern vorhanden) diese explizit aufrufen, um eine ordnungsgemäße Löschung des Basisklassenabschnitts der Instanz sicherzustellen.

So in der Tat es ist ein destructor (aber man kann es explizit nennen sich selbst als Klasse-Methode).

jedoch von other answers sondern auch aus den Wikipedia:

In einer Sprache mit einem automatischen Garbage Collection-Mechanismus, würde es schwierig sein, deterministisch den Aufruf eines destructor, um sicherzustellen, und daher werden diese Sprachen im Allgemeinen als ungeeignet für RAII [Ressourcen Acquisition Is Initialization]

werden, so sollten Sie sich so gut wie nie __del__ Umsetzung, aber es gibt Ihnen die Möglichkeit, so in einigen (selten?) zu tun Fälle verwenden

+3

Ein Anwendungsfall besteht darin, sicherzustellen, dass die kritische Ressource bereinigt wird, bevor das Objekt durch den Müll gesammelt wird. I.e. Überprüfen Sie in '__del__', ob die Ressource normal geschlossen ist, und wenn nicht, tun Sie dies und geben Sie eine Warnung aus. – doublep

1

Ist del wirklich ein Destruktor?

Nein, __del__ Methode ist kein destructor, ist nur eine normale Methode, die Sie aufrufen können, wenn Sie eine Operation ausgeführt werden soll, aber es heißt immer, bevor der Garbage Collector das Objekt zerstört. Denken Sie daran wie eine saubere oder letzte Willensmethode.

+0

Wird der Aufruf zu __del__ passieren, wenn es passieren muss oder wie es ist, was wir als finalize() in Java haben, hörte ich einige verweisende finalize() Aufruf ist unberechenbar –

+0

@Explorer_N, wird immer von Python-Interpreter aufgerufen werden, wenn das Objekt wird gerade gelöscht. – Netwave

5

Wie die anderen Antworten bereits gezeigt haben, sollten Sie wahrscheinlich nicht __del__ in Python implementieren. Wenn Sie sich in der Situation befinden, dass Sie wirklich einen Destruktor benötigen (wenn Ihre Klasse beispielsweise eine Ressource umschließt, die explizit geschlossen werden muss), verwendet der Pythonic-Weg context managers.

+0

Kontextmanager-Link war gut, implementiert jedes Objekt (einschließlich Benutzertyp) den Kontextmanager? –

+1

@Explorer_N Nein, Sie müssen es selbst tun. Und sie haben auch nicht alle die gleichen sematics. Aber es ist leicht gemacht. – glglgl

+1

@Explorer_N: Während Sie normalerweise die Funktionalität selbst für benutzerdefinierte Klassen implementieren müssen, ist es oft sehr einfach, die Helfer aus dem ['contextlib'-Modul] (https://docs.python.org/3/library/contextlib.html) zu verwenden). –