web-dev-qa-db-fra.com

False == 0 et True == 1 dans Python un détail de la mise en œuvre ou est-il garanti par le langage?

Est-il garanti que False == 0 et True == 1, dans Python (en supposant qu'ils ne sont pas réaffectés par l'utilisateur)? Par exemple, est-il garanti que le code suivant produira toujours les mêmes résultats, quelle que soit la version de Python (existants et probablement futurs)?

0 == False  # True
1 == True   # True
['zero', 'one'][False]  # is 'zero'

Toute référence à la documentation officielle serait très appréciée!

Edit: Comme indiqué dans de nombreuses réponses, bool hérite de int. La question peut donc être reformulée comme suit: "La documentation indique-t-elle officiellement que les programmeurs peuvent compter sur des booléens héritant d'entiers, avec les valeurs 0 et 1? ". Cette question est pertinente pour l'écriture de code robuste qui n'échouera pas à cause des détails de l'implémentation!

226
Eric O Lebigot

Dans Python 2.x, ceci est non garanti car il est possible pour True et False de être réaffecté. Toutefois, même si cela se produit, les valeurs booléennes True et booléennes False sont toujours correctement renvoyées pour permettre des comparaisons.

Dans Python 3.x True et False sont des mots-clés et seront toujours égaux à _1_ et _0_.

Dans des circonstances normales, dans Python 2 et toujours dans Python 3:

False objet est de type bool qui est une sous-classe de int:

_object
   |
 int
   |
 bool
_

C’est la seule raison pour laquelle, dans votre exemple, _['zero', 'one'][False]_ fonctionne. Cela ne fonctionnerait pas avec un objet qui n'est pas une sous-classe d'entier, car l'indexation par liste ne fonctionne qu'avec des entiers ou avec des objets qui définissent une méthode __index__ (grâce mark-dickinson ).

Modifier:

C’est vrai de la version actuelle de python et de celle de Python 3. Le docs pour python 2.6 et le - docs pour Python les deux disent:

Il existe deux types d'entiers: [...] Entiers (int) [...] Booléens (bool)

et dans la sous-section boolean:

Booléens: ils représentent les valeurs de vérité False et True [...] Les valeurs booléennes se comportent comme les valeurs 0 et 1, respectivement, dans presque tous les contextes, à l'exception des chaînes "False" ou "True" converties en chaînes. "sont retournés, respectivement.

Il y a aussi, pour Python 2 :

Dans les contextes numériques (par exemple, lorsqu'ils sont utilisés comme arguments d'un opérateur arithmétique), ils [False et True] se comportent comme les entiers 0 et 1, respectivement.

Les booléens sont donc explicitement considérés comme des entiers dans Python 2.6 et 3.

Donc, vous êtes en sécurité jusqu'à ce que Python 4 apparaisse. ;-)

169
Olivier Verdier

Lien vers le PEP traitant du nouveau type bool dans Python 2.3: http://www.python.org/dev/peps/pep-0285/ .

Lors de la conversion d'un bool en un entier, la valeur entière est toujours 0 ou 1, mais lors de la conversion d'un entier en bool, la valeur booléenne est True pour tous les entiers sauf 0.

>>> int(False)
0
>>> int(True)
1
>>> bool(5)
True
>>> bool(-5)
True
>>> bool(0)
False
71

Dans Python 2.x, cela n’est pas du tout garanti:

>>> False = 5
>>> 0 == False
False

Donc ça pourrait changer. Dans Python 3.x, True, False et None sont mots réservés , le code ci-dessus ne fonctionnerait donc pas.

En général, avec des booléens, vous devez supposer que, bien que False ait toujours une valeur entière égale à 0 (tant que vous ne la changez pas, comme ci-dessus), True peut avoir une autre valeur. Je ne m'appuierais pas nécessairement sur la garantie que True==1, mais sur Python 3.x, ce sera toujours le cas, quoi qu'il arrive.

22
Daniel G