Seite 1 von 1

Überladung von Operatoren - maximum recursive depth exceeded

Verfasst: Montag 26. März 2007, 15:31
von Blauer Fasan
Also als aller erstes einen wundeschönen guten Tag an euch alle. Ich bin vor kurzem auf dieses Forum gestoßen und finde dieses wirklich eine gute Idee!

Nun bin ich ein relativer Neuling in Python (und auch allgemein im Programmieren) und habe eine kleine Klasse: "PokerKarte" geschrieben.
Hier habe ich versucht Vergleichsoperatoren mit der Methode "__cmp__" zu überladen.

Code: Alles auswählen

def __cmp__(self, other):

    a = self.gibZahl
    b = other.gibZahl

    if a < b: return -1
    elif a == b: return 0
    else: return 1
"gibZahl" liefert einen Integer-Wert zurück, welches den Stellenwert der Karte darstellt (z.B.: 14 == Ass).

Nun instantiiere ich zwei PokerKarte-nObjekte um sie miteinander zu vergleichen:

Code: Alles auswählen

pikAss = PokerKarte("Pik", 14)
herzBube = PokerKarte("Herz", 11)

if pikAss > herzBube:
    print "Pik Ass ist höher als Herz Bube!"

Nun stellt sich mir folgende Fehlermeldung in den Weg:

Code: Alles auswählen

[Der Pfad] line 32, in __cmp__
if a < b: return -1
RuntimeError: maximum recursion depth exceeded in cmp
Diese drei Zeilen tauchen sehr oft hintereinander auf, also scheint dort irgendetwas sehr häufig hintereinander zu passieren, obwohl ich in meinem Code meines Wissens keinerlei Schleifen oder rekursive Funktionen implementiert habe.

Mich würde es sehr freuen, wenn ihr mir helfen könntet und ich bitte um Vergebung, falls ich etwas ungenau oder unpräzise geschildert habe (In diesem Fall bitte ich um Nachfrage).

Also schon einmal im Voraus, vielen Dank :D

Verfasst: Montag 26. März 2007, 15:45
von Rebecca
Bist du dir wirklich sicher, dass a und b Intergers sind? Du kannst das pruefen indem du

Code: Alles auswählen

print type(a), type(b)
in die __cmp__-Methode einbaust.

Verfasst: Montag 26. März 2007, 15:54
von Blauer Fasan
Also ich habe das Programm kurzer Hand mit Idle geöffnet, da es mir in der cmd-Konsole nicht möglich war, den Anfang zu sehen, da halt so viele Fehlermeldungen hintereinander kamen. Dort stand:

<type instancemethod>

Was ich mir persönlich nicht erklären kann. :(

Aber nochmal die gibZahl() Methode:

Code: Alles auswählen

def gibZahl(self):
        return self.__zahl
Und self.__zahl ist halt die übergebene Zahl, in diesem Fall 14 bzw. 11.

Verfasst: Montag 26. März 2007, 16:00
von Rebecca
Du musst die Methode auch aufrufen: a.gibZahl() (man beachte die Klammern). So sind a und b nur Referenzen auf die Methode selbst (und genau das sagt type)

Verfasst: Montag 26. März 2007, 16:04
von Blauer Fasan
Es funktioniert, es lag wirklich an den Klammern

Vielen Dank! Wie konnte ich sowas nur übersehen, also nochmals vielen Dank! :D :D :D

Verfasst: Montag 26. März 2007, 17:00
von BlackJack
Statt `gibZahl()` könnte man auch `__int__()` benutzen und die Karte in ein `int` Umwandeln. Oder man setzt den Kartenwert als Attribut und nicht als Methode, oder wird der jedesmal neu berechnet?

Code: Alles auswählen

    def __int__(self):
        return self.value

    def __cmp__(self, other):
        return cmp(int(self), int(other))

# oder

    def __cmp__(self, other):
        return cmp(self.value, other.value)

Verfasst: Montag 26. März 2007, 20:54
von Blauer Fasan
Elegante Lösung! Danke :)