2010-05-04 8 views
168

¿Está garantizado que False == 0 y True == 1, en Python? Por ejemplo, ¿está de alguna manera garantizado que el siguiente código siempre producirá los mismos resultados, cualquiera sea la versión de Python (tanto existente como, probablemente, futuros)?¿Es False == 0 y True == 1 en Python un detalle de implementación o está garantizado por el idioma?

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

¡Cualquier referencia a la documentación oficial sería muy apreciada!

Editar: Como se señala en muchas respuestas, bool hereda de int. Por lo tanto, la pregunta puede ser reformulada como: "? ¿La documentación oficial dice que los programadores pueden confiar en booleanos que heredan de números enteros, con los valores 0 y 1". ¡Esta pregunta es relevante para escribir código sólido que no fallará debido a los detalles de implementación!

+4

Si sospecha que se trata de un detalle, ¿por qué no evitar los detalles? ¿Por qué hacer una pregunta como esta? Es trivial evitar depender de este tipo de funcionalidad. Para su ejemplo, use un diccionario en lugar de una lista. ¿Qué problema estás teniendo? ¿Por qué preguntar esto? –

+50

@ S.Lott: hay muchas razones para hacer la pregunta anterior. Por lo tanto, hay casos en los que confiar en booleanos que son enteros simplifica el código: ¿tiene que cambiarlo? O bien, puede detectar lugares en un código escrito por otra persona que confía en que los booleanos son enteros: ¿interrumpe lo que está modificando en el código para "corregir" el código existente, o puede estar seguro de que la codificación actual es sonido? ? Hay una plétora de otros ejemplos. En términos más generales, es bueno conocer las reglas del juego, para que pueda jugarlo bien y programarlo de manera sensata. – EOL

+0

@EOL: ¿me puede dar un ejemplo de "confiar en que booleanos siendo enteros simplifican su código"? No puedo imaginar tal cosa. "¿Interrumpes lo que estás modificando en el código para" arreglar "el código existente, o puedes estar seguro de que la codificación actual es sólida?" La pregunta parece técnica, no "¿cómo puedo enfrentarlo?" Las reglas son simples: ** no depende de los detalles de implementación **. Entonces, ¿por qué preguntar acerca de un detalle de implementación? –

Respuesta

130

En Python 2.x esto es no garantizada, ya que es posible que True y False ser reasignado. Sin embargo, incluso si esto sucede, Boolean True y boolean False se devuelven correctamente para las comparaciones.

En Python 3.x True y False son palabras clave y siempre serán igual a 1 y 0.

En circunstancias normales en Python 2, y siempre en Python 3:

False objeto es de tipo bool que es una subclase de int:

object 
    | 
int 
    | 
bool 

Es la única razón por la cual en su ejemplo , ['zero', 'one'][False] funciona.No funcionaría con un objeto que no sea una subclase de entero, porque la indexación de listas solo funciona con enteros u objetos que definen un método __index__ (gracias mark-dickinson).

Editar:

Es verdad de la versión actual de pitón, y de la de Python 3. El docs for python 2.6 y la docs for Python 3 ambos dicen:

Hay dos tipos de números enteros: [.. .] los enteros (int) [...] booleanos (bool)

y en la subsección booleano:

Booleanos: representan los valores de verdad Los valores booleanos falsos y [...] verdaderos se comportan como los valores 0 y 1, respectivamente, en casi todos los contextos, con la excepción de que cuando se convierten en una cadena, las cadenas "Falso" o "Verdadero" son devueltos, respectivamente.

Así booleanos se consideran explícitamente como enteros en Python 2.6 y 3.

por lo que está seguro hasta Python 4 se presente. ;-)

+2

0 == 0.0 devuelve verdadero mientras ['cero', 'uno'] [0.0] falla. ['cero', 'uno'] [Falso] funciona porque bool es una subclase de int. (int .__ subclases __() devuelve []) – luc

+0

Acepte que mi respuesta no está completa. :) Your señala la razón correcta Supongo – luc

+17

Nitpick: cualquier objeto que proporcione un método '__index__' se puede usar como un índice de lista; no solo subclases de 'int' o' long'. –

-6

falsa es un bool. Tiene un tipo diferente. Es un objeto diferente de 0 que es un número entero.

0 == False devuelve True False porque es echado a un entero. int (Falso) devuelve 0

La documentación pitón del operador == dice (ayuda ('==')):

Los operadores <, >, ==, >=, <= y comparar != los valores de dos objetos Los objetos no necesitan tener el mismo tipo. Si ambos son números, se convierten a un tipo común.

Como consecuencia, False se convierte en un número entero por la necesidad de la comparación. Sin embargo, es diferente de 0.

>>> 0 is False 
False 
+20

Esto no es del todo correcto: 'bool' es una subclase de' int', por lo que en un sentido muy real, un bool * es * un entero. Por ejemplo, 'isinstance (True, int)' devuelve True. Y la comprobación de igualdad no convierte el bool en un int, ya que no es necesaria ninguna conversión: simplemente llama a 'int .__ cmp__' directamente. Tenga en cuenta que 'bool .__ cmp__ es int .__ cmp__' también se evalúa como' True'. –

+3

-1 para esta respuesta. Descripción incorrecta de la relación entre bool e int (en Python 2). 'isinstance (True, int)' => True. Es decir, True * IS * es un número entero y no requiere conversión. – ToolmakerSteve

+0

Tenía un script que devolvía False o un Int ... que usaba 'while response false' y' while response == False' no .. ¡Gracias! –

57

Enlace al PEP discutir el nuevo tipo bool en Python 2.3: http://www.python.org/dev/peps/pep-0285/.

Cuando se convierte un bool a un int, el valor entero es siempre 0 o 1, pero al convertir un int a un bool, el valor booleano es cierto para todos los números enteros excepto 0.

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

En Python 2.x, no se garantiza en absoluto:

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

por lo que podría cambiar. En Python 3.x, True, False y None son reserved words, por lo que el código anterior no funcionaría.

En general, con booleanos, debe suponer que mientras que False siempre tendrá un valor entero de 0 (siempre que no lo modifique, como se indicó anteriormente), True podría tener cualquier otro valor. No necesariamente confiaría en ninguna garantía de que True==1, pero en Python 3.x, este siempre será el caso, no importa qué.

+2

Re "True podría tener cualquier otro valor. No necesariamente me basaría en ninguna garantía de que True == 1". En realidad, PUEDE confiar en True == 1, según http://www.python.org/dev/peps/pep-0285/, y especifique http://docs.python.org/2/reference/datamodel. html # the-standard-type-hierarchy "Los valores booleanos se comportan como los valores 0 y 1, respectivamente, en casi todos los contextos ..." No estoy diciendo que sea imposible anular esto en Py 2 reasignando True o False, pero estoy diciendo que a menos que algún programador en su proyecto sea un idiota y haga tal reasignación, el comportamiento está garantizado. – ToolmakerSteve

Cuestiones relacionadas