1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

[python] Destruktor von übergeordneter Klasse aufrufen

Dieses Thema im Forum "CGI, Perl, Python, Ruby, Power Shell" wurde erstellt von Enumerator, 19. Mai 2010.

  1. Enumerator

    Enumerator Mitglied Kamel

    Hi!

    Aus Spaß an der Freude dacht' ich mir heute zum Feierabend: "...was soll's? Lernst' halt Python..".
    Bin auch recht fix voran gekommen, allerdings bereitet mir die OOP etwas Kopfzerbrechen: Vielleicht kann mir jemand mal erklären warum im folgenden der (vererbte) Destruktor der Klasse "Person" nicht aufgerufen wird?
    Bzw. warum Sätze wie "John Lennon stirbt." und "Ringo Starr lebt aber noch!" nicht ausgegeben werden?
    Code (Python):
    1. #!/usr/bin/env python
    2. # coding=UTF-8
    3.  
    4. import sys
    5. echo = sys.stdout.write
    6.  
    7. class Person:
    8.     def __init__(self, name):
    9.         self.name = name
    10.         print self.__class__._Artikel, self.__class__.__name__, self.name, self.__class__._Entsteht
    11.     def __del__(self):
    12.         print self.__class__._Artikel, self.__class__.__name__, self.name, self.__class__._Verschwindet
    13.     def sagt(self, nachricht):
    14.         sys.stdout.write(self.name)
    15.         print "sagt:", nachricht
    16.  
    17. Person._Entsteht = "entsteht."
    18. Person._Verschwindet = "veschwindet."
    19. Person._Artikel = "Die"
    20.  
    21. class Mensch(Person):
    22.     def __del__(self):
    23.         print self.name, "geht's nicht gut..."
    24. #       Person.__del__(self)
    25.  
    26. Mensch._Entsteht = "wird geboren."
    27. Mensch._Verschwindet = "stirbt."
    28. Mensch._Artikel = "Der"
    29.  
    30. class Musiker(Mensch):
    31.     pass
    32.  
    33. namen = [ "Stuart Sutcliffe", "Ringo Starr", "John Lennon", "Pete Best",
    34.     "Paul McCartney", "George Harrison" ]
    35. musiker = {}
    36.  
    37. for iter in range(len(namen)):
    38.     musiker[namen[iter]] = Musiker(namen[iter])
    39.  
    40. reihenfolge = (0, 2, -1)
    41.  
    42. for iter in reihenfolge:
    43.     del musiker[namen[iter]]
    44.  
    45. Mensch._Verschwindet = "lebt aber noch!"
    Die auskommentierte Zeile 24 wirft einen sehr abenteuerlichen Fehler den ich zwar verstehe --
    dennoch überrascht es mich das das nicht die Lösung des o.g. Problems ist, zumal es im Konstruktor funktioniert..

    Dank und Gruß
    Enum
     
  2. Matthias Reitinger

    Matthias Reitinger ɐɯıǝɹ Premium-User

    Weil die Semantik von __del__ nun mal so ist (Quelle).

    Ich kann im Konstruktor keinen zu Person.__del__(self) äquivalenten Aufruf erkennen. Was genau meinst du damit? __del__ entspricht (nicht nur in dieser Hinsicht) übrigens nicht dem Destruktor aus bspw. C++. Es wird nämlich nicht mal garantiert, dass die Methode beim Skriptende für alle noch lebenden Objekte aufgerufen wird. In den meisten Fällen braucht man aber Destruktoren in einer Sprache mit einem GC auch überhaupt nicht.

    Grüße,
    Matthias
     
  3. Enumerator

    Enumerator Mitglied Kamel

    Hi Matthias!

    Sorry, ich hatte zuvor im Skript eine weitere Klasse:
    Code (Python):
    1. class Gruppe(Person):
    2.     def __init__(self, name):
    3.         Person.__init__(self, name)
    4.         self.mitglieder = []
    5. # ...
    Kein Zweifel. Dennoch ist es IMHO wichtig, das Verhalten des GC genau zu kennen, u.A. um mit (weak-) Referenzen und Dergleichen sowie C-modulen sicher spielen zu können.
    In diesem speziellen Fall wollte ich eigentlich nur in Erfahrung bringen, wann genau welcher Destruktor aufgerufen wird: Wenn z.B. die Klasse Gruppe das einzige Objekt ist welches überhaupt Referenzen zu bestimmten Personen hält ist es doch sehr wichtig, ob zuerst die Destruktoren der Person Klasse (für die Mitglieder) aufgerufen werden oder erst die Gruppe vernichtet wird...
    Wie auch immer, die gestellten Fragen hat das Skript für mich ja beantwortet. Nur hat es auch eine neue Frage aufgeworfen - und die ist Thema dieses Threads :p

    Ok. Wie zur H*lle kann ich dann ein solches verhalten implementieren? Tante Google hat zwar ein paar Tweaks ausgespuckt (so in der Richtung for base in self.__class__.__bases__) aber keine davon scheint wirklich sicher, schon gar nicht wenn weitere Ableitungen vorgenommen werden -
    Und soweit mich meine Englisch-Kenntnisse bringen, beschreibt die Doku die Du verlinkt hast auch nur das Problem und nicht die Lösung...

    Gruß
    Enum
     

Diese Seite empfehlen