2011-12-31 12 views
9

¿Hay alguna manera más pitonica de hacer esto?Manera pitónica de pasar argumentos de palabra clave en condicional

if authenticate: 
    connect(username="foo") 
else: 
    connect(username="foo", password="bar", otherarg="zed") 
+0

¿Qué pasa con lo que tienes? "No te repitas" es una buena regla a seguir, pero no si hace que tu código sea más complicado. –

+0

No será mucho más complicado, por lo que valoro DRY sobre la complejidad en este caso. – ash

Respuesta

16
  1. Se puede añadirlos a una lista de kwargs así:

    connect_kwargs = dict(username="foo") 
    if authenticate: 
        connect_kwargs['password'] = "bar" 
        connect_kwargs['otherarg'] = "zed" 
    connect(**connect_kwargs) 
    

    Esto a veces puede ser útil cuando se tiene un complicado conjunto de opciones que se pueden pasar a una función. En este caso simple, creo que lo que tienes es mejor, pero esto podría considerarse más pythonic porque no repite username="foo" dos veces como el OP.

  2. Este enfoque alternativo también se puede usar, aunque solo funciona si sabe cuáles son los argumentos predeterminados. Tampoco lo consideraría muy "pitónico" debido a las cláusulas duplicadas if.

    password = "bar" if authenticate else None 
    otherarg = "zed" if authenticate else None 
    connect(username="foo", password=password, otherarg=otherarg) 
    
+0

+1 Yo habría publicado lo mismo. –

+2

La opción 1 es buena, la opción 2 no. –

+0

La opción 1 es más líneas y menos directa que la pregunta original =/ – Charlie

-2

O, más concisamente:

connect(**(
    {'username': 'foo', 'password': 'bar', 'otherarg': 'zed'} 
    if authenticate else {'username': 'foo'} 
)) 
+1

¿Cómo es eso más conciso? – jterrace

+0

Es una expresión única que evita referencias repetidas a un temporal para acumular los argumentos para pasar. –

+0

Quise decir con respecto al original. Es exactamente lo mismo que el OP, simplemente reorganizado. – jterrace

0

Sólo pensé en tirar mi sombrero en el anillo:

authenticate_kwargs = {'password': "bar", 'otherarg': "zed"} if authenticate else {} 
connect(username="foo", **authenticate_kwargs) 
2

La versión de la OP es en realidad bien en este caso donde el número de argumentos incondicionales es bajo en comparación con el número de argumentos condicionales. Esto se debe a que solo los argumentos incondicionales tienen que repetirse en ambas ramas de la construcción if-else. Sin embargo, a menudo me encuentro con el caso opuesto, es decir, el número de argumentos incondicionales es alto en comparación con el de los condicionales.

Esto es lo que yo uso:

connect(username="foo", 
     **(dict(password="bar", otherarg="zed") if authenticate else {})) 
Cuestiones relacionadas