python python-2.x

python - ¿Por qué la asignación a True/False no funciona como espero?



python-2.x (5)

Como parte de responder a otra pregunta, escribí el siguiente código cuyo comportamiento parece extraño a primera vista:

print True # outputs true True = False; print True # outputs false True = True; print True # outputs false True = not True; print True # outputs true

¿Alguien puede explicar este extraño comportamiento? Creo que tiene algo que ver con el modelo de objetos de Python, pero no estoy seguro.

Es la versión 2.5.2 de Cygwin.


En 2.x, True y False no son palabras clave, por lo que es posible seguir de cerca los elementos integrados.


Imagina esto en su lugar:

A = True B = False print A # true A = B; print A # false A = A; print A # false, because A is still false from before A = not A; print A # true, because A was false, so not A is true

Exactamente lo mismo está sucediendo, pero en su versión es confuso, porque no espera que pueda redefinir True and False.


Puede restaurar fácilmente los valores originales usando comparaciones booleanas simples:

True = 1==1 False = 1==0

O al convertir literales enteros en bools:

True = bool(1) # actually every number except 0 works False = bool(0)


Puede verificar si True / False es una palabra clave:

>>> import keyword >>> keyword.iskeyword(''True'') False

Como no es (en mi versión), asignar True = False solo significa "Verdadero" es otro nombre de "variable".


Python tiene estos dos (entre otros) objetos incorporados. Son solo objetos; al principio, todavía no tienen ningún nombre, pero para saber a qué nos referimos, llamémoslos 0x600D y 0xBAD .

Antes de comenzar a ejecutar un script de Python (2.x), el nombre True se vincula al objeto 0x600D , y el nombre False se vincula al objeto 0xBAD , por lo que cuando el programa se refiere a True , se ve en 0x600D .

Debido a que 0x600D y 0xBAD saben que generalmente se usan con los nombres True y False , eso es lo que producen cuando se imprimen, es decir, el método __str__ de 0x600D devuelve ''True'' y así sucesivamente.

True = False

ahora vincula el nombre True a un objeto diferente. A partir de ahora, los dos nombres True y False refieren al mismo objeto 0xBAD , que, cuando se imprime, genera False .

True = True

realmente no hace nada: toma el objeto al que se hace referencia con el nombre True y vincula el nuevo (y antiguo) nombre True a este objeto. Dado que (debido al paso anterior) True refiere a 0xBAD antes de esto, todavía se refiere a 0xBAD después de esto. Por lo tanto, la impresión sigue emitiendo False .

True = not True

primero toma el objeto al que está vinculado el nombre True , que es 0xBAD . Da este objeto al operador not . not importa (ni sabe) qué nombre se usa aquí para referirse a 0xBAD , simplemente sabe que cuando se le da 0xBAD debe devolver 0x600D . Este valor de retorno se otorga al operador de asignación = , vinculando el nombre True a este objeto.

Dado que el nombre True ahora una vez más se refiere al objeto 0x600D , la llamada print True 0x600D True y el mundo vuelve a ser bueno.