gibt es eigentlich in Python eine Möglichkeit, Objekten irgendwie Destruktoren zuzuweisen????
würde mich mal interresieren, da könnt ich in manchen programmen nämlich einiges vereinfachen ...
mfg cime
Destruktoren
-
- User
- Beiträge: 52
- Registriert: Dienstag 21. September 2004, 06:58
- Wohnort: Adelzhausen
- Kontaktdaten:
Da wär ich aber vorsichtig mit, da __del__ meines Wissens nach erst ausgeführt wird, wenn der garbage collector mitkriegt, dass dein Objekt nicht mehr verwendet wird und es aufräumt. Wenn Du dein Ojekt aber explizit mit löschts, wird __del__ anscheinend sofort ausgeführt. Ich weiss aber nicht, ob das verlässlich ist. Es kann auch sein, dass das Objekt zur zum Löschen für den GC markiert wird, das weiss ich nicht genau.
Sebastian
Code: Alles auswählen
del meinObjekt
Sebastian
Genauso ist es:raist1314 hat geschrieben:Es kann auch sein, dass das Objekt zur zum Löschen für den GC markiert wird
Code: Alles auswählen
>>> class Foo:
... def __del__(self):
... print "bye"
...
>>> a = Foo()
>>> b = a
>>> del a
>>> del b
bye
Ja, interessant, dann ist der Sinn von __del__ ein anderer,raist1314 hat geschrieben:Das dachte ich mir... also eher ne unsichere Sache...
Sebastian
als man es sich so vorstellt.
von der Python Docu:
"del x" doesn't directly call x.__del__() -- the former decrements the reference count for x by one, and the latter is only called when x's reference count reaches zero.
Nur bei der letzten zu löschenden Instanz wird __del__ aufgerufen.
Also ich hab mir das instinktiv immer so vorgestellt
Unter C würde ich auch keinen Destruktor eines Objekts aufrufen, auf das noch ein pointer verweist. (Habs oft genug unabsichtlich gemacht, ein Grund warum ich jetzt Python bevorzuge)
Ich denke das grundsätzliche Verständnisproblem, wenn man es denn so nennen darf, liegt darin, dass man del in python nur den Verweis auf ein Objekt löscht, während es in C++ wirklich das Objekt zerstört.
(Ist auch sehr pythonic nebenbei, weil mit dem c++-del würd ich implizit den "wert" einer anderen variable verändern, die noch auf mein gelöschtes Objekt verweist. Explicit is better than implicit.)
Unter C würde ich auch keinen Destruktor eines Objekts aufrufen, auf das noch ein pointer verweist. (Habs oft genug unabsichtlich gemacht, ein Grund warum ich jetzt Python bevorzuge)
Ich denke das grundsätzliche Verständnisproblem, wenn man es denn so nennen darf, liegt darin, dass man del in python nur den Verweis auf ein Objekt löscht, während es in C++ wirklich das Objekt zerstört.
(Ist auch sehr pythonic nebenbei, weil mit dem c++-del würd ich implizit den "wert" einer anderen variable verändern, die noch auf mein gelöschtes Objekt verweist. Explicit is better than implicit.)
__del__ ist genau das, wonach ich gesucht habe ... thx ...
PS: wo in der doku steht das eigentlich genau (ich find mich in der Pythondoku immer nich so wirklich zurecht)???Francesco hat geschrieben:von der Python Docu:
"del x" doesn't directly call x.__del__() -- the former decrements the reference count for x by one, and the latter is only called when x's reference count reaches zero.
ich gehe meist so vor (WinXP):cime hat geschrieben:__del__ ist genau das, wonach ich gesucht habe ... thx ...
PS: wo in der doku steht das eigentlich genau (ich find mich in der Pythondoku immer nich so wirklich zurecht)???Francesco hat geschrieben:von der Python Docu:
"del x" doesn't directly call x.__del__() -- the former decrements the reference count for x by one, and the latter is only called when x's reference count reaches zero.
Ich verwende C:\Python24\Doc\Python24.chm (shortcut am desktop, da
die häufig gebraucht wird).
Ich verwende nicht den inhalt, da ich durch "Suchen" meist viel schneller
zum Ziel komme. __del__ suchen, dann ist der erste Eintrag
3.3.1 "Basic customization", das mir im gelben Feld "Note:" die erforderliche Information brachte.
@henning:
Kann mich damit (noch) nicht recht anfreunden.
Wozu brauche ich dann eine __del__ Funktion überhaupt.
Was macht es für einen Sinn, wenn bei der letzten Instanz einer Klasse
dann der "Destruktor" aufgerufen wird.
Für mich logischer:
del object =>__del__ (dann ist die referenz weg und das object auch)
wenn ich versuche, es aufzurufen, dann bekomme ich ohnehin einen NameError.
Da wär ich mir nicht sicher. Die Methode wird erst aufgerufen wenn das Objekt wirklich vom Interpreter/Garbage Collector freigegeben wird. Wann dieser Zeitpunkt kommt ist nicht sicher. Auch bei CPython kann es sein, das es erst beim "herunterfahren" des Interpreters passiert. Und dann solltest Du in `__del__()` nichts mehr benutzen von dem Du nicht ganz sicher bist noch eine Referenz zu haben. Selbst ein `print` kann dann ein Problem werden, wenn `sys.stdout` schon "abgeräumt" wurde.cime hat geschrieben:__del__ ist genau das, wonach ich gesucht habe ...
Lass die Finger von `__del__()` und stelle lieber eine Methode bereit, die Du explizit aufrufst, wenn Du mit dem Objekt fertig bist.
Du brauchst keine `__del__()` Methode. So einfach ist das.Francesco hat geschrieben:@henning:
Kann mich damit (noch) nicht recht anfreunden.
Wozu brauche ich dann eine __del__ Funktion überhaupt.
Was macht es für einen Sinn, wenn bei der letzten Instanz einer Klasse
dann der "Destruktor" aufgerufen wird.
Die Methode wird nicht bei der letzten Instanz einer Klasse aufgerufen sondern dann wenn keine Referenz mehr auf das Objekt verweist. Wie unsinnig wäre es denn bitteschön ein Objekt zu zerstören, auf das noch zugegriffen werden kann!?
Das spiegelt aber überhaupt nicht die Funktionsweise von Python wieder. Das erste Missverständnis scheint schon durch die Namenswahl bei ``del object`` durch: Du löscht mit ``del`` kein Objekt sondern den Namen!Für mich logischer:
del object =>__del__ (dann ist die referenz weg und das object auch)
wenn ich versuche, es aufzurufen, dann bekomme ich ohnehin einen NameError.
Code: Alles auswählen
In [6]: a_name = object()
In [7]: a_name
Out[7]: <object object at 0x40056440>
In [8]: another_name = a_name
In [9]: del a_name
In [10]: a_name
---------------------------------------------------------------------------
exceptions.NameError Traceback (most recent call last)
/home/bj/<console>
NameError: name 'a_name' is not defined
In [11]: another_name
Out[11]: <object object at 0x40056440>
Warum stört ihr euch alle so sehr daran den Zeitpunkt der Zerstörung nicht genau festlegen zu können?Francesco hat geschrieben:
@henning:
Kann mich damit (noch) nicht recht anfreunden.
Wozu brauche ich dann eine __del__ Funktion überhaupt.
Was macht es für einen Sinn, wenn bei der letzten Instanz einer Klasse
dann der "Destruktor" aufgerufen wird.
Also warum __del__ nützlich sein kann:
Nehmen wir an, du hast ein Objekt mit dem du eine Verbindung repräsentierst, zum Beispiel zu einem FTP-Server oder was-weiß ich.
Wenn das Objekt zerstört wird, macht es Sinn, zu gucken, ob die Verbindung noch besteht und wenn nicht, diese höflich (z.B. mit einem QUIT) zu beenden.
Zugegeben, man braucht es nicht oft, aber es kann nützlich sein.
Zur Zeitpunkt-Sache:
Wenn man so coded, dass man mit dem Löschen eines Objekts eigentlich Funktionen ausführen will, die nicht unmittelbar mit der Objektzerstörung zu tun haben, dann macht man ja eh irgendwas falsch.
Andernfalls sollte der genaue Zeitpunkt kein Problem darstellen.
Und falls irgendwie doch und es total wichtig ist, dass __del__ genau in dem Moment ausgeführt wird, in dem die letzte Referenz auf das Objekt erlischt, muss man halt den garbage-collector ausschalten. (Dann muss man aber aufpassen keine zirkulären Referenzen zu haben!)
(Wobei ich mir bei dem gc-Kram nicht so sicher bin)
-
- User
- Beiträge: 1790
- Registriert: Donnerstag 28. Oktober 2004, 16:33
- Wohnort: Graz, Steiermark - Österreich
- Kontaktdaten:
__del__ kann ihc beispiels weise verwenden wenn ich in einem webapplication thread die geteilte datenbankverbindung trennen will.
TUFKAB – the user formerly known as blackbird
Wieso unsicher? Wenn jemand die Instanz noch benutzt, darf sie doch nicht einfach gelöscht werden!raist1314 hat geschrieben:Das dachte ich mir... also eher ne unsichere Sache...
In C++ kann man da ganz schön auf die Nase fallen:
Code: Alles auswählen
void Foobar::Finish(){
delete this;
}
Genau dieses Verhalten von Python will man in C++ doch auch gerne haben; deswegen gibt es ja auto_ptr und weitere smart pointer. Es gibt sogar einen Garbagecollector für C++.
Oder worauf wolltest du hinaus?
Nur wenn Du damit leben kannst, das nicht sicher gestellt ist, das __del__ wirklich irgendwann vor Programmende aufgerufen wird. Also bei einem Server der sehr lange läuft eben auch sehr spät.blackbird hat geschrieben:__del__ kann ihc beispiels weise verwenden wenn ich in einem webapplication thread die geteilte datenbankverbindung trennen will.
-
- User
- Beiträge: 1790
- Registriert: Donnerstag 28. Oktober 2004, 16:33
- Wohnort: Graz, Steiermark - Österreich
- Kontaktdaten:
Das ist ja auch Sinn einer persistenten DatenbankverbindungBlackJack hat geschrieben:Nur wenn Du damit leben kannst, das nicht sicher gestellt ist, das __del__ wirklich irgendwann vor Programmende aufgerufen wird. Also bei einem Server der sehr lange läuft eben auch sehr spät.
TUFKAB – the user formerly known as blackbird