Objekte werden nicht zerstört

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
D503
User
Beiträge: 3
Registriert: Mittwoch 16. Februar 2011, 13:41

Hallo Zusammen,

ich hoffe das wir jetzt kein python4dummys thread :D

Folgender Code:

Code: Alles auswählen

class Cchild():
    parent = None
        
class Cparent():
    childs = []
    
    def printChilds(self):
        print len(self.childs)
    
    def add(self, child):
        child.parent = self
        self.childs.append(child)

    
def test():
    parent = Cparent()
    
    parent.add(Cchild())
    
    parent.printChilds()
    
if __name__ == '__main__':
    test()
    test()
gibt zurück:

1
2

müsste aber zurückgeben:

1
1

Hatte zunächst den Verdacht das es an der parent/child zirkulär Referenzierung liegt, aber selbst wenn ich die parent Referenzierung im child aus kommentiere habe ich das gleiche Ergebnis.

Kann mir da jemand helfen?

Grüße

D503
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Verwende halt keine Klassenattribute, sondern Instanzattribute:

Code: Alles auswählen

class Cchild():
    def __init__(self):
        self.parent = None
       
class Cparent():
    def __init__(self):
        self.childs = []
   
    def printChilds(self):
        print len(self.childs)
   
    def add(self, child):
        child.parent = self
        self.childs.append(child)

   
def test():
    parent = Cparent()
   
    parent.add(Cchild())
   
    parent.printChilds()
   
if __name__ == '__main__':
    test()
    test()
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

snafu hat geschrieben:Verwende halt keine Klassenattribute, sondern Instanzattribute:
Und bitte benutze den korrekten Plural "children". "childs" tut beim Lesen ja schon fast körperlich weh.
D503
User
Beiträge: 3
Registriert: Mittwoch 16. Februar 2011, 13:41

vielen dank!

gelobe besserung.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Und mit dem Ansatz wird es tatsaechlich zu dem im Titel angesprochenen Problem kommen, suchst du vielleicht weakref?
D503
User
Beiträge: 3
Registriert: Mittwoch 16. Februar 2011, 13:41

weakref war eins meiner versuche.

die lösung ist im grunde das ich die klassenattribute zur laufzeit beim instanzieren explizit noch mal initialisieren muss.

das schein etwas python spezifisches zu sein das ich nicht wusste. in vb, c# ist das nicht so und in c++ wirst du dazu gezwungen.

man lernt nie aus.

momentan funzt das ohne weakref bei mir. muss ich mal genau schauen ob ich mir dadurch nen memory leak einbauen und die gc das object wegen der zirkulär referenzierung nicht löschen kann. dann muss ich doch den umweg über weakref gehen.

vielen dank nochmal
BlackJack

@D503: Du musst nicht Klassenattribute "nochmal" initialisieren sondern Instanzattribute verwenden. Und das ist in VB, C#, und C++ genau so!

Es ist ein grosser Unterschied ob Du ein Objekt an die *Klasse* bindest, oder an jedes einzelne Exemplar.

Falls dieser `C`-Präfix für Klasse stehen soll, dann lass den bitte weg. Klassen sind normalerweise das Einzige was mit in Python in "MixedCase"-Schreibweise benennt, also ist ein zusätzlicher "Typpräfix" unnötig und verwirrt nur. Für alles andere ausser Konstanten ist übrigens Kleinbuchstaben und Unterstriche üblich, also `print_children()` statt `printChildren()`.

Speicherlecks gibt es bei zirkulären Objektreferenzen nicht, solange man nicht anfängt auf den Objekten `__del__()`-Methoden zu implementieren. Das sollte man aber sowieso nicht tun, solange man reine Python-Klassen schreibt.
Antworten