Definieren der "Boolness" einer Klasse in Python

73

Warum funktioniert das nicht so, wie man es naiv erwartet hat?

class Foo(object):
    def __init__(self):
        self.bar = 3
    def __bool__(self):
        return self.bar > 10

foo = Foo()

if foo:
    print 'x'
else:
    print 'y'

(Die Ausgabe ist x)

wim
quelle

Antworten:

71

Fügen Sie dies aus Gründen der Python 2-3-Kompatibilität einfach Ihrem Beispiel hinzu:

Foo.__nonzero__ = Foo.__bool__

oder erweitern Sie die ursprüngliche Definition von Foo um:

__nonzero__ = __bool__

Sie können sie natürlich auch umgekehrt definieren, wo sich der Methodenname befindet __nonzero__und dem Sie ihn zuweisen __bool__, aber ich denke, der Name __nonzero__ist nur ein Erbe der ursprünglichen C-Ishness von Pythons Interpretation von Objekten als wahr oder falsch, basierend auf ihrer Äquivalenz mit Null. Fügen Sie einfach die obige Anweisung hinzu, und Ihr Code funktioniert mit Python 2.x und funktioniert automatisch, wenn Sie auf Python 3.x aktualisieren (und schließlich die Zuweisung an ablegen __nonzero__).

PaulMcG
quelle
Wohin würden diese Einfügungen gehen? Ich vermute, das erste könnte unmittelbar nach der Zeile stehen return self.bar > 10(0 Leerzeichen eingerückt) und das zweite könnte unmittelbar vor der Zeile stehen def __init__(self):(4 Leerzeichen eingerückt). Ist das korrekt? Oder müsste der zweite nach der __bool__Definition gehen?
Käfer
65

Die __bool__Methode wird in Python 3 verwendet. Für Python 2 möchten Sie __nonzero__.

Cat Plus Plus
quelle
richtig, seltsam aber wahr. Gut zu sehen, dass sie die Implementierung auf den "einen offensichtlichen Weg"
geändert haben
6
@wim: Nicht zu seltsam. Der __nonzero__()Methodenname ist wesentlich älter als die Einführung des Typs boolin Python. Vorher verwenden Sie booleinfach die ganzen Zahlen 0und 1.
Sven Marnach
1
@SvenMarnach: Ihr hattet 0und 1? Dilbert ;-)
JS.