Al investigar Queue.py en Python 2.6, encontré esta construcción que me pareció un poco extraña:
def full(self):
"""Return True if the queue is full, False otherwise
(not reliable!)."""
self.mutex.acquire()
n = 0 < self.maxsize == self._qsize()
self.mutex.release()
return n
Si maxsizees 0, la cola nunca está llena.
Mi pregunta es ¿cómo funciona para este caso? ¿Cómo 0 < 0 == 0se considera falso?
>>> 0 < 0 == 0
False
>>> (0) < (0 == 0)
True
>>> (0 < 0) == 0
True
>>> 0 < (0 == 0)
True

>>> (0) < (0 == 0), claramente no lo es.n = 0 < self.maxsize == self._qsize()en primer lugar, en ningún idioma. Si sus ojos tienen que moverse de un lado a otro de la línea varias veces para descubrir lo que está sucediendo, no es una línea bien escrita. Simplemente divídalo en varias líneas.Respuestas:
Creo que Python tiene un manejo de casos especial para secuencias de operadores relacionales para hacer que las comparaciones de rango sean fáciles de expresar. Es mucho más agradable poder decir
0 < x <= 5que decir(0 < x) and (x <= 5).Estas se llaman comparaciones encadenadas . Y ese es un enlace a la documentación para ellos.
Con los otros casos de los que habla, los paréntesis obligan a un operador relacional a aplicarse antes que al otro, por lo que ya no son comparaciones encadenadas. Y dado que
TrueyFalsetiene valores como enteros, obtiene las respuestas que hace de las versiones entre paréntesis.fuente
Porque
es
False. Puede encadenar operadores de comparación y se expanden automáticamente en las comparaciones por pares.EDITAR: aclaración sobre verdadero y falso en Python
En Python
TrueyFalseson solo instancias debool, que es una subclase deint. En otras palabras,Truerealmente es solo 1.El punto de esto es que puede usar el resultado de una comparación booleana exactamente como un entero. Esto lleva a cosas confusas como
Pero esto solo sucederá si entre paréntesis las comparaciones para que se evalúen primero. De lo contrario, Python expandirá los operadores de comparación.
fuente
'success' if result_code == 0 else 'failure'puede reescribirse ya que('error', 'success')[result_code == 0], antes de esto, nunca había visto un booleano utilizado para seleccionar un elemento en una lista / tupla.El comportamiento extraño que experimentas proviene de la habilidad de las pitones para encadenar las condiciones. Como encuentra que 0 no es menor que 0, decide que toda la expresión se evalúa como falsa. Tan pronto como separe esto en condiciones separadas, cambiará la funcionalidad. Inicialmente está probando esencialmente eso
a < b && b == cpara su declaración original dea < b == c.Otro ejemplo:
fuente
a < b && b == ces lo mismo quea < b == cOOEsta es una comparación encadenada. Devuelve verdadero si cada comparación por pares a su vez es verdadera. Es el equivalente a
(0 < 0) and (0 == 0)Esto es equivalente a lo
0 < Trueque se evalúa como Verdadero.Esto es equivalente a lo
False == 0que se evalúa como Verdadero.Equivalente a lo
0 < Trueque, como anteriormente, se evalúa como Verdadero.fuente
Mirando el desmontaje (los códigos de bytes) es obvio por qué
0 < 0 == 0esFalse.Aquí hay un análisis de esta expresión:
Observe las líneas 0-8: estas líneas verifican si
0 < 0obviamente regresaFalsea la pila de Python.Ahora observe la línea 11:
JUMP_IF_FALSE_OR_POP 23Esto significa que si0 < 0regresa,Falserealice un salto a la línea 23.Ahora,
0 < 0esFalse, entonces se realiza el salto, que deja la pila con unFalsevalor de retorno para toda la expresión0 < 0 == 0, aunque la== 0parte ni siquiera esté marcada.Entonces, para concluir, la respuesta es como se dijo en otras respuestas a esta pregunta.
0 < 0 == 0Tiene un significado especial. El compilador evalúa esto en dos términos:0 < 0y0 == 0. Como con cualquier expresión booleana complejaandentre ellas, si la primera falla, la segunda ni siquiera está marcada.Espero que esto aclare un poco las cosas, y realmente espero que el método que utilicé para analizar este comportamiento inesperado anime a otros a intentar lo mismo en el futuro.
fuente
Como se mencionó en otros,
x comparison_operator y comparison_operator zes el azúcar sintáctico(x comparison_operator y) and (y comparison_operator z)con la ventaja de que y solo se evalúa una vez.Entonces su expresión
0 < 0 == 0es realmente(0 < 0) and (0 == 0), lo que evalúaFalse and Truecuál es la justaFalse.fuente
Tal vez este extracto de los documentos puede ayudar:
Estas fueron comparaciones, pero como estás encadenando comparaciones , debes saber que:
fuente
Aquí está, en todo su esplendor.
fuente
Estoy pensando que Python está haciendo algo extraño entre la magia. Lo mismo que
1 < 2 < 3significa que 2 está entre 1 y 3.En este caso, creo que está haciendo [middle 0] es mayor que [left 0] e igual a [right 0]. El medio 0 no es mayor que el izquierdo 0, por lo que se evalúa como falso.
fuente