rekursiver Aufruf innerhalb einer Klasse

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
Sanne1612
User
Beiträge: 3
Registriert: Dienstag 18. April 2017, 08:45

Hallo liebes Forum,

ich möchte gerne eine Baumstruktur mittels Python implementieren und alle Funktionen in einer Klasse bündeln.
Nun gibt es aber scheinbar ein Problem mit der Rekursivität der Struktur. Die Initialisierung ist geläufig.
Jetzt soll die Funktion gesamt() Die Summe der einzelnen Blätter errechnen.

Code: Alles auswählen

class Baum(object):
    """ Klasse für eine einfache Baumstruktur """

    def __init__(self, value, left = None, right = None):
        """ Neuen Knoten des Baumes initialisieren """
        self.left = left
        self.right = right
        self.value = value
     
     def gesamt(self):
        if self == None: return 0
        return self.left.gesamt() + self.right.gesamt() + self.value
        
if __name__ == "__main__":
    baum = Baum(1, Baum(2), Baum(3))
    print baum.gesamt()
Fehlermeldung: AttributeError: 'NoneType' object has no attribute 'gesamt'

Ich scheine an irgendeiner Stelle einen Denkfehler zu haben. Kann mir jemand weiterhelfen?

Beste Grüße Sanne
Zuletzt geändert von Anonymous am Dienstag 18. April 2017, 09:29, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

self.left oder self.right können None sein, du prüfst ja nur auf self.

Noch ein Tipp: Eine Prüfung auf None sollte man mit 'is' machen, nicht per '=='.
BlackJack

@Sanne1612: `self` auf `None` zu prüfen macht auch gar keinen Sinn weil `self` nie `None` sein dürfte. Denn das würde ja bedeuten man hätte die `gesamt()`-Methode eines `None`-Objekts aufgerufen und nicht die eines `Baum`-Objekts. Und `None`-Objekte haben gar keine `gesamt()`-Methode. Wie die Fehlermeldung ja auch sehr deutlich sagt. :-)
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Sanne1612: Deine Methode gesamt() scheint aus Gefühl geschrieben zu sein. Sie müsste wie folgt lauten:

Code: Alles auswählen

    def gesamt(self):
        result = self.value
        if self.left:
            result += self.left.gesamt()
        if self.right:
            result += self.right.gesamt()
        return result
Versuche zu erklären, was hier Zeile für Zeile geschieht.
Sanne1612
User
Beiträge: 3
Registriert: Dienstag 18. April 2017, 08:45

Dann wäre das die Lösung?

Code: Alles auswählen

def gesamt(self):
        if self is None: return 0
        if self.left is not None and self.right is not None:
            return self.left.gesamt() + self.right.gesamt() + self.value
Schmeißt mir nun einen Typfehler:
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'

Was ich nicht ganz verstehe ist, warum die Funktion:

Code: Alles auswählen

def gesamt(baum): 
   if baum == None: return 0 
   return gesamt(baum.links) + gesamt(baum.rechts) + baum.inhalt
außerhalb der Klasse definiert fehlerlos funktioniert und in der Klasse integriert nicht.

Liebe Grüße Sanne
Zuletzt geändert von Anonymous am Dienstag 18. April 2017, 11:40, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Sanne1612: Weil auf der Klasse als Methode definiert `self`, wie schon gesagt, niemals `None` ist und die Methode nur auf `Baum` definiert ist, aber nicht auf `None`. Du versuchst aber die Methode `gesamt()` auf `None`-Objekten aufzurufen. Und dort gibt's die halt nicht.

Edit: Zum neuen Versuch: Du prüfst ob `left` und `right` nicht `None` sind. Das ist aber nicht der einzige Fall der auftreten kann. Und was passiert wenn die Bedingung nicht erfüllt ist? Was denkst Du was die Methode dann zurück gibt?
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sanne1612: Deine neue Lösung berücksichtigt die Fälle, dass left und/oder right None sind nicht. Was wird in diesen Fällen zurückgegeben?
Sanne1612
User
Beiträge: 3
Registriert: Dienstag 18. April 2017, 08:45

Er hatte bei mir noch nicht die neuen Forumbeiträge geladen, daher ging das etwas durcheinander.
Ich habe es nun grundsätzlich verstanden und versuche die weiteren Funktionen, wie einfügen etc.
abzuleiten.

Vielen Dank für die Unterstützung,
Sanne
Antworten