2016-06-17 7 views
4

Kann mir jemand eine Erklärung geben, warum isinstance() im folgenden Fall True zurückgibt? Ich habe False erwartet, als ich den Code geschrieben habe.Python vergleicht boolean und int mit isinstance

print isinstance(True, (float, int)) 
True 

Meine Vermutung wäre, dass sein Python interne Unterklassen, als null und eins - wheter float oder int - beide zu bewerten, wenn sie als boolean verwendet, aber nicht wissen, den genauen Grund.

Was wäre der pythischste Weg, um eine solche Situation zu lösen? Ich könnte type() verwenden, aber in den meisten Fällen gilt dies als weniger Python.

Antwort

13

Aus historischen Gründen ist bool eine Unterklasse von int, daher ist True eine Instanz von int. (Ursprünglich hatte Python keinen bool-Typ, und Dinge, die Wahrheitswerte zurückgaben, gaben 1 oder 0 zurück. When they added bool, Wahr und Falsch mussten aus Gründen der Abwärtskompatibilität für 1 und 0 so groß wie möglich sein, daher die Unterklassen.)

Der richtige Weg zum "Lösen" hängt davon ab, was genau Sie für das Problem halten.

  • Wenn Sie True ein int sein stoppen wollen, na ja, so schlimm. Das wird nicht passieren.
  • Wenn Sie booleans erkennen wollen und behandeln sie anders aus anderen Ints, können Sie das tun:

    if isinstance(whatever, bool): 
        # special handling 
    elif isinstance(whatever, (float, int)): 
        # other handling 
    
  • Wenn Sie Objekte, deren spezifische Klasse erkennen wollen, ist genau float oder int, Subklassen Ablehnung Sie kann das tun:

    if type(whatever) in (float, int): 
        # Do stuff. 
    
  • Wenn Sie alle Floats und Ints erkennen möchten, tun Sie das bereits.
+0

Es ist der zweite Fall. Das heißt, man muss sich um die Reihenfolge der Vergleiche dieser eingebauten Typen kümmern - verständlich angesichts der Vererbung, aber ziemlich ungewöhnlich für Python. – jake77

0

Ja, das ist richtig, es ist eine Unterklasse von int ist, können Sie es mit Hilfe des Dolmetschers überprüfen können:

>>> int.__subclasses__() 
[<type 'bool'>] 
0

Wenn Sie nur für int überprüfen möchten:

if type(some_var) is int: 
    return True 

else: 
    return False