Considera este código:

def say_hi(english: bool, name: str) -> str:
    if name != "":
        if english:
            greeting = f"Hi, {name}!"
    else:
        if english:
            greeting = "Hey there!"
    if english:
        greeting = greeting + "foo bar"
    if not english:
        greeting = "I speak only English, sorry."
    return greeting

¿Cuál es la mejor manera de optimizar este código para que no tenga 3 veces el mismo if statmenet (if english:) en un bloque de código? O, tal vez una pregunta diferente: ¿este código de declaración if repetitivo coincide con los estándares PEP de Python?

-3
neisor 12 ene. 2022 a las 12:27
1
¿Qué esperas que sea greeting si english es falso?
 – 
khelwood
12 ene. 2022 a las 12:29
if not english: raise NameError en la parte superior de la función, luego elimine la marca en cualquier otro lugar...
 – 
deceze
12 ene. 2022 a las 12:30
Eso no es importante en este caso. El código anterior sirve como ejemplo. Ese no es un fragmento de código que se deba usar, sino solo un fragmento de código para demostrar mi pregunta.
 – 
neisor
12 ene. 2022 a las 12:31
2
Esta es simplemente una lógica mal estructurada, o al menos lógica expresada de manera ineficiente. No necesita un PEP para eso, y depende mucho del caso específico cómo la lógica podría expresarse de una manera más forma compacta, pero todavía fácil de mantener.
 – 
deceze
12 ene. 2022 a las 12:40

6 respuestas

La mejor respuesta

¿Por qué no invertir el orden de las declaraciones if?

def say_hi(english: bool, name: str) -> str:
    if english:
        if name != "":
                greeting = f"Hi, {name}!"
        else:
                greeting = "Hey there!"
        greeting = greeting + "foo bar"
    else:
        greeting = "I speak only English, sorry."
    return greeting
2
matszwecja 12 ene. 2022 a las 12:33

Podrías hacer algo como esto:

def say_hi(english: bool, name: str) -> str:
    if not english:
        greeting = "I speak only English, sorry."
    else:
        greeting = (f"Hi, {name}!" if name else "Hey there!") + "foo bar"
    return greeting
2
Jakob Madsen 12 ene. 2022 a las 12:37

Esto no es específico de Python y no necesita ningún PEP, es simplemente parte de escribir Good Code™ y debe aplicarse a todos y cada uno de los códigos que escriba. Revíselo y aplique simplificaciones paso a paso para reducirlo a su forma más mínima, simple y comprensible.

Estoy usando su código original aquí, ya que muestra una lección importante adicional:

def say_hi(english: bool, name: str) -> str:
    if name != "":
        if english:
            greeting = f"Hi, {name}!"
    else:
        if english:
            greeting = "Hey there!"
    if english:
        greeting = greeting + "foo bar"
    return greeting
  1. Tenga en cuenta que las primeras ramas if..else contienen la misma verificación if english y que ambas no hacen nada si english es falsa. Entonces puedes revertir ese cheque:

    if english:
        if name != "":
            greeting = f"Hi, {name}!"
        else:
            greeting = "Hey there!"
    
  2. Reconoce que podrías alinear este if..else interno:

    if english:
        greeting = f"Hi, {name}!" if name != "" else "Hey there!"
    

    Esto es discutible y depende de su preferencia personal, pero creo que es aplicable aquí.

  3. Reconoce que ahora tienes la misma condición verifica dos veces:

    if english:
        greeting = f"Hi, {name}!" if name != "" else "Hey there!"
    if english:
        greeting = greeting + "foo bar"
    

    Condensar eso a:

    if english:
        greeting = f"Hi, {name}!" if name != "" else "Hey there!"
        greeting = greeting + "foo bar"
    
  4. Ahora algo que solo existía en su código original: reconozca que ahora tiene un error en su función:

    def say_hi(english: bool, name: str) -> str:
        if english:
            greeting = f"Hi, {name}!" if name != "" else "Hey there!"
            greeting = greeting + "foo bar"
        return greeting
    

    Su función básicamente no hace nada si english es falsa y producirá NameError en la última línea. Esto ahora es más fácil de reconocer con la lógica simplificada. Entonces, para reconocer ese comportamiento explícitamente y producir exactamente el mismo comportamiento con menos código, sería esto:

    def say_hi(english: bool, name: str) -> str:
        if not english:
            raise NameError
    
        greeting = f"Hi, {name}!" if name != "" else "Hey there!"
        greeting = greeting + "foo bar"
        return greeting
    
  5. Reconoce que puedes condensar las dos últimas líneas:

    def say_hi(english: bool, name: str) -> str:
        if not english:
            raise NameError
    
        greeting = f"Hi, {name}!" if name != "" else "Hey there!"
        return greeting + "foo bar"
    

    Usted podría condensar las dos últimas líneas nuevamente, pero yo no lo haría por razones de legibilidad.

  6. Reconoce que las cadenas vacías son falsas y todas las demás cadenas son verdaderas, así que simplifica la verificación name != "":

    greeting = f"Hi, {name}!" if name else "Hey there!"
    

Y, por supuesto, en lugar de raise NameError devolvería un mensaje diferente, como en su código fijo:

def say_hi(english: bool, name: str) -> str:
    if not english:
        return "I speak only English, sorry."

    greeting = f"Hi, {name}!" if name else "Hey there!"
    return greeting + "foo bar"

Así hemos condensado seis ramas lógicas en una y media (irónicamente).

1
deceze 12 ene. 2022 a las 13:08

Yo iria con

def say_hi(english: bool, name: str) -> str:
    if name != "" and english:
        greeting = f"Hi, {name}!"
    elif name == "" and english:
        greeting = "Hey there!"
    return greeting + "foo bar" if english else /*greeting*/
0
anthino12 12 ene. 2022 a las 12:33
def say_hi(english: bool, name: str) -> str:
    if name != "":
        if english: #   return True
            greeting = f"Hi, {name}!"
    else:
        if english: # return True
            greeting = "Hey there!"
    if english: #return True
        greeting = greeting + "foo bar"
    return greeting

Es por eso que cuando llamas a la función con False se ha pasado como inglés generará un error, porque todas las declaraciones if que escribiste siempre devolverán True

Para evitar esta declaración, agregue si bloquee el identificador en inglés cuando es Flase así

def say_hi(english: bool, name: str) -> str:
    
    if name != "" and english:
            greeting = f"Hi, {name}! foo bar" 
    elif english:
            greeting = "Hey there!"
        
    else:
        greeting = "False" 
0
naif123321 12 ene. 2022 a las 12:55
  • Fallando rápido. es decir, coloque el código que falla rápidamente en la parte superior.
  • las variables boolenas deben comenzar con "es" siempre que sea posible
# Without Foo bar
def say_hi_2(is_english_speaker: bool, name: str):
    if not is_english_speaker:
        return "I speak only English, sorry."

    if not name:
        return "Hey There"

    return f"Hi, {name}"

# With foo bar
def say_hi(is_english_speaker: bool, name: str):
    if not is_english_speaker:
        return "I speak only English, sorry."

    greeting_template = "{} foo bar"
    if not name:
        return greeting_template.format("Hey There")

    return greeting_template.format(f"Hi, {name}")

1
Antonio Mande 12 ene. 2022 a las 12:52