web-dev-qa-db-fra.com

python comparant booléen et int utilisant isinstance

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.

12
jake77

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.

  • Si vous voulez que 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 voulez détecter tous les flottants et tous les objets, vous le faites déjà.
23
user2357112

Si vous souhaitez uniquement vérifier int:

if type(some_var) is int:
    return True

else:
    return False
1
Eyal Levin

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;
0
Venfah Nazir

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'>]
0
sbz