Pregunta

Por alguna razón esta función me confundió:

def protocol(port):
    return port == "443" and "https://" or "http://"

Puede alguien explicar el orden de lo que está sucediendo detrás de las escenas para que esto funcione de la manera que lo hace.

I entendido como esto hasta que probé:

o bien a)

def protocol(port):
    if port == "443":
        if bool("https://"):
            return True
    elif bool("http://"):
        return True
    return False

o B)

def protocol(port):
    if port == "443":
        return True + "https://"
    else:
        return True + "http://"

Es esto algún tipo de caso especial en Python, o estoy completamente malentendido cómo declaraciones trabajo?

¿Fue útil?

Solución

Es una vieja-ish idioma; insertando paréntesis para mostrar prioridad,

(port == "443" and "https://") or "http://"

retornos x and y y si x es Truish, x si x es falsish; a or b, viceversa, devoluciones a si es Truish, de lo contrario b.

Así que si port == "443" es cierto, esto devuelve el RHS de la and, es decir, "https://". De lo contrario, el and es falso, por lo que el or pone en juego y vuelve ` "http: //"., su RHS

En Python moderna, una mejor manera de hacer traducir esta vieja-ish modismo es:

"https://" if port == "443" else "http://"

Otros consejos

and devuelve el operando de la derecha si la izquierda es cierto. or devuelve el operando de la derecha si la izquierda es falsa. De lo contrario, ambos devuelven el operando de la izquierda. Se dice que se unen .

C and X or Y es el primer intento de larga duración por los usuarios de Python para proxy para C ? X : Y

En su mayor parte funciona, excepto si es X False - esto ha dado lugar a muchos errores en el código Python, por lo que en el Python FAQ , encontrará la solución más correcta, porque siendo (C and [X] or [Y])[0] una lista con un solo elemento, independientemente de su valor booleano evaluado, es siempre True! Por ejemplo: [None] es True pero None no lo es. El ejemplo de la OP arriba funciona debido a que la cadena que representa X no está vacío.

Sin embargo, todo esto cambió en Python 2.5, cuando se añadió el ternario o el operador condicional a la lengua, lo que permite utilizar el limpiador de X if C else Y como se ha dicho en otras críticas aquí. Si ve el código utilizando el formato anterior, es debido a que el usuario ha pasado mucho tiempo programador de Python que no ha adoptado la nueva sintaxis, sin embargo, se cortó-n-pegar otro código de edad, o su empleador sigue utilizando 2.4.x ( o versiones anteriores), etc.

Este es un truco feo que no se recomienda. Funciona a causa del comportamiento de cortocircuito de and y or y que se devuelva el uno de sus argumentos en lugar de un valor booleano. Usando esta técnica da un riesgo de introducir errores difíciles de encontrar, así que no se usan en el nuevo código.

Aquí hay un ejemplo de cómo el lenguaje and/or puede dar un resultado inesperado:

>>> foo = 'foobar'
>>> bar = 'foobar'
>>> x = 0
>>> y = 1
>>> (foo == bar) and x or y   # Will this return the value of x if (foo == bar)?
1

Prefiero lugar la notación nueva:

return "https://" if port == "443" else "http://"

Es posible que desee leer sobre el "y / o truco" de Python en este artículo La peculiar naturaleza de y y O en Python . Es un poco como el IIF() en VBA o VB, o ?: en lenguajes C-estilo.

Esta construcción funciona porque '' se despliega en el código siguiente:

a y b ->

if a:
  return b
else:
  return a

a o b ->

if a:
  return a
else:
  return b

Con todas las buenas respuestas, me encontré con estas declaraciones me ayudan a recordar esto mejor encajan y cómo mis funciona el cerebro (y esperemos que para algunos de más por ahí):

  • “y" devuelve el primer elemento falso (por ejemplo, Ninguno, ‘’, [], (), {}, 0) o el último elemento en su defecto (por ejemplo, no hallados falsos)

  • “o" devuelve el primer elemento Verdadero o el último elemento (por ejemplo, ningún verdadero encontrados) **

En resumen

  • todos ellos devuelven el primer elemento que decide el resultado de la declaración. (En el peor de los casos, el último elemento de la secuencia)

Tenga en cuenta esta regla también se aplica a un encadenado todos "y" o la totalidad "o" declaración

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top