2011-12-31 15 views
9

Esiste un modo più plateale per fare ciò?Modo Pythonic per passare gli argomenti delle parole chiave condizionali

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

Cosa c'è di sbagliato con quello che hai? "Non ripeterti" è una buona regola da seguire, ma non se rende il tuo codice più complicato. –

+0

Non sarà molto più complicato, quindi in questo caso apprezzo molto la complessità. – ash

risposta

16
  1. Li potrebbe aggiungere a un elenco di kwargs come questo:

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

    Questo a volte può essere utile quando si dispone di una serie complessa di opzioni che possono essere passate a una funzione. In questo semplice caso, penso che quello che hai è meglio, ma questo potrebbe essere considerato più pythonic perché non si ripete lo username="foo" due volte come l'OP.

  2. Questo approccio alternativo può anche essere utilizzato, sebbene funzioni solo se si conoscono gli argomenti predefiniti. Inoltre, non considererei molto "pythonic" a causa delle clausole duplicate if.

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

+1 avrei postato lo stesso. –

+2

L'opzione 1 è buona, l'opzione 2 no. –

+0

L'opzione 1 è più linee e meno diretta della domanda originale =/ – Charlie

-2

O, più conciso:

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

Come è più conciso? – jterrace

+0

È un'espressione singola che evita riferimenti ripetuti a un temporaneo per accumulare gli argomenti da passare. –

+0

intendevo rispetto all'originale. È esattamente la stessa cosa dell'OP, appena riorganizzato. – jterrace

0

Ho pensato di gettare il cappello sul ring:

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

versione del PO è in realtà ok in questo caso dove il numero di argomenti incondizionati è basso rispetto al numero di argomenti condizionali. Questo perché solo gli argomenti incondizionati devono essere ripetuti in entrambi i rami del costrutto if-else. Tuttavia, mi imbatto spesso nel caso opposto, cioè il numero di argomenti incondizionati è elevato rispetto a quello dei condizionali.

Questo è quello che uso:

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