Quelqu'un peut-il m'expliquer pourquoi isinstance()
renvoie True dans le cas suivant? Je m'attendais à Faux lors de l'écriture du code.
print isinstance(True, (float, int))
True
J'imagine que les sous-classes internes de python, zéro et un, que ce soit float ou int, sont toutes deux évaluées lorsqu'elles sont utilisées comme booléens, mais ne connaissent pas la raison exacte.
Quel serait le moyen le plus pythonique de résoudre une telle situation? Je pourrais utiliser type()
mais dans la plupart des cas, cela est considéré comme moins pythonique.
Pour des raisons historiques, bool
est une sous-classe de int
, donc True
est une instance de int
. (A l'origine, Python n'avait pas de type bool et les valeurs renvoyées par true renvoyaient 1 ou 0. Lorsqu'ils ont ajouté bool
, True et False devaient être des remplacements instantanés pour 1 et 0 autant que possible pour assurer la compatibilité ascendante. , d’où le sous-classement.)
La bonne façon de "résoudre" cela dépend de ce que vous considérez être le problème.
True
cesse d'être int
, eh bien, dommage. Ça ne va pas arriver.Si vous voulez détecter des booléens et les manipuler différemment des autres ints, vous pouvez le faire:
if isinstance(whatever, bool):
# special handling
Elif isinstance(whatever, (float, int)):
# other handling
Si vous souhaitez détecter des objets dont la classe spécifique est exactement float
ou int
, rejetant des sous-classes, vous pouvez le faire:
if type(whatever) in (float, int):
# Do stuff.
Si vous souhaitez uniquement vérifier int
:
if type(some_var) is int:
return True
else:
return False
Voir quelques comportements (pas si bizarre) de python sur bool et int
>>> 1 == True
True
>>> 0 == False
True
>>> True*5 == 0
False
>>> True*5 == 5
True
>>>
Comment interchangeables peuvent-ils être utilisés ...!
De boolobject.h (win py 2.7) je peux voir un typedef de int pour bool obj. Il est donc assez évident que bool a hérité de quelques traits du visage d'int.
#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef PyIntObject PyBoolObject;
Oui, c'est vrai, c'est une sous-classe d'int, vous pouvez le vérifier en utilisant l'interpréteur:
>>> int.__subclasses__()
[<type 'bool'>]