python - Comparando boolean e int usando isinstance
comparison (4)
Por razones históricas,
bool
es una subclase de
int
, por lo que
True
es una instancia de
int
.
(Originalmente, Python no tenía tipo bool, y las cosas que devolvían valores de verdad devolvían 1 o 0.
Cuando agregaban
bool
, True y False tenían que ser reemplazos directos para 1 y 0 tanto como fuera posible para la compatibilidad con versiones anteriores, de ahí la subclase .)
La forma correcta de "resolver" esto depende exactamente de lo que consideres que es el problema.
-
Si quieres que
True
deje de ser unint
, bueno, muy mal. Eso no va a suceder. -
Si desea detectar booleanos y manejarlos de manera diferente a otras entradas, puede hacerlo:
if isinstance(whatever, bool): # special handling elif isinstance(whatever, (float, int)): # other handling
-
Si desea detectar objetos cuya clase específica es exactamente
float
oint
, rechazando subclases, puede hacerlo:if type(whatever) in (float, int): # Do stuff.
- Si quieres detectar todos los flotadores e ints, ya lo estás haciendo.
¿Alguien puede darme una explicación de por qué
isinstance()
devuelve True en el siguiente caso?
Esperaba False, al escribir el código.
print isinstance(True, (float, int))
True
Supongo que su subclasificación interna de Python, como cero y uno, ya sea flotante o int, ambos se evalúan cuando se usan como booleanos, pero no saben la razón exacta.
¿Cuál sería la forma más pitónica de resolver tal situación?
Podría usar
type()
pero en la mayoría de los casos esto se considera menos pitónico.
Sí, esto es correcto, es una subclase de int, puede verificarlo usando el intérprete:
>>> int.__subclasses__()
[<type ''bool''>]
Si solo desea verificar
int
:
if type(some_var) is int:
return True
else:
return False
Vea algunos comportamientos (no tan extraños) de python en bool e int
>>> 1 == True
True
>>> 0 == False
True
>>> True*5 == 0
False
>>> True*5 == 5
True
>>>
¡Qué intercambiables se pueden usar ...!
Desde boolobject.h (win py 2.7) puedo ver un typedef de int para bool obj. Por lo tanto, es bastante evidente que bool ha heredado algunas características faciales de int.
#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef PyIntObject PyBoolObject;