Im ersten Test versucht Python, das Objekt in einen boolWert zu konvertieren, falls dies noch nicht geschehen ist. Grob fragen wir das Objekt: Sind Sie bedeutungsvoll oder nicht? Dies erfolgt mit dem folgenden Algorithmus:
Wenn das Objekt über eine __nonzero__spezielle Methode verfügt (wie auch über numerische integrierte Funktionen intund float), wird diese Methode aufgerufen. Es muss entweder einen boolWert zurückgeben, der dann direkt verwendet wird, oder einen intWert, der berücksichtigt wird, Falsewenn er gleich Null ist.
Andernfalls, wenn das Objekt eine hat __len__spezielle Methode (wie auch Behälter Einbauten, list, dict, set, tuple, ...), ist es diese Methode aufruft, einen Behälter unter Berücksichtigung , Falsewenn es leer ist (Länge ist null).
Andernfalls wird das Objekt berücksichtigt, es Truesei denn, Nonein diesem Fall wird es berücksichtigt False.
Im zweiten Test wird das Objekt auf Gleichheit mit verglichen None. Hier fragen wir das Objekt: "Sind Sie diesem anderen Wert gleich?" Dies erfolgt mit dem folgenden Algorithmus:
Wenn das Objekt eine __eq__Methode hat, wird es aufgerufen, und der Rückgabewert wird dann in einen boolWert konvertiert und verwendet, um das Ergebnis der zu bestimmen if.
Andernfalls wird das Objekt __cmp__aufgerufen , wenn es über eine Methode verfügt. Diese Funktion muss eine Rückgabe intder Reihenfolge der beiden Objekte zurückgeben ( -1if self < other, 0if self == other, +1if self > other).
Andernfalls wird das Objekt auf Identität verglichen (dh es bezieht sich auf dasselbe Objekt, wie vom isBediener getestet werden kann ).
Mit dem isBediener ist ein weiterer Test möglich . Wir würden das Objekt fragen: "Sind Sie dieses bestimmte Objekt?"
Im Allgemeinen würde ich empfehlen, den ersten Test mit nicht numerischen Werten zu verwenden, den Test auf Gleichheit zu verwenden, wenn Sie Objekte derselben Art (zwei Zeichenfolgen, zwei Zahlen, ...) vergleichen und nur dann auf Identität prüfen möchten Verwenden von Sentinel-Werten ( Nonedh nicht initialisiert für ein Mitgliedsfeld, zum Beispiel oder bei Verwendung der getattroder der __getitem__Methoden).
Zusammenfassend haben wir:
>>> class A(object):
... def __repr__(self):
... return 'A()'
... def __nonzero__(self):
... return False
>>> class B(object):
... def __repr__(self):
... return 'B()'
... def __len__(self):
... return 0
>>> class C(object):
... def __repr__(self):
... return 'C()'
... def __cmp__(self, other):
... return 0
>>> class D(object):
... def __repr__(self):
... return 'D()'
... def __eq__(self, other):
... return True
>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:
... print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \
... (repr(obj), bool(obj), obj == None, obj is None)
'': bool(obj) -> False, obj == None -> False, obj is None -> False
(): bool(obj) -> False, obj == None -> False, obj is None -> False
[]: bool(obj) -> False, obj == None -> False, obj is None -> False
{}: bool(obj) -> False, obj == None -> False, obj is None -> False
0: bool(obj) -> False, obj == None -> False, obj is None -> False
0.0: bool(obj) -> False, obj == None -> False, obj is None -> False
A(): bool(obj) -> False, obj == None -> False, obj is None -> False
B(): bool(obj) -> False, obj == None -> False, obj is None -> False
C(): bool(obj) -> True, obj == None -> True, obj is None -> False
D(): bool(obj) -> True, obj == None -> True, obj is None -> False
None: bool(obj) -> False, obj == None -> True, obj is None -> True