2011-01-01 4 views
16

Supponiamo di avere una funzione python che accetta due argomenti, ma voglio che il secondo arg sia facoltativo, con il valore predefinito che è stato passato come primo argomento. Quindi, voglio fare qualcosa del genere:In Python, posso specificare l'impostazione predefinita di un argomento di funzione in termini di altri argomenti?

def myfunc(arg1, arg2=arg1): 
    print (arg1, arg2) 

Tranne che non funziona. L'unica soluzione che posso pensare è questa:

def myfunc(arg1, arg2=None): 
    if arg2 is None: 
     arg2 = arg1 
    print (arg1, arg2) 

C'è un modo migliore per farlo?

+0

Sto solo ripensando a questo, potrebbe essere possibile ottenere con un decoratore. Non sarà chiaro cosa faccia a prima vista, quindi probabilmente è una cattiva idea, ma è un'idea. – marcog

risposta

17

Come dice @Ignacio, non è possibile farlo. Nel tuo ultimo esempio, potresti avere una situazione in cui None è un valore valido per arg2. Se questo è il caso, è possibile utilizzare un valore sentinella:

sentinel = object() 
def myfunc(arg1, arg2=sentinel): 
    if arg2 is sentinel: 
     arg2 = arg1 
    print (arg1, arg2) 

myfunc("foo")   # Prints 'foo foo' 
myfunc("foo", None)  # Prints 'foo None' 
+2

@martineau Grazie per la modifica, bel posto! – marcog

+2

Nessun problema - risposta eccellente, a proposito. – martineau

+0

probabilmente meglio impostare semplicemente arg2 su Nessuno e controllare quello invece di preoccuparsi di un oggetto sentinella personalizzato a meno che non sia necessario gestire l'utente fornito Nessuno diverso dall'impostazione predefinita – user234461

3

Non proprio. Gli altri nomi degli argomenti non esistono finché non viene effettivamente inserita la funzione.

+0

Ma puoi riordinarlo leggermente cambiando la clausola 'if' nella soluzione alternativa a:' arg2 = arg2 o arg1' –

+1

@Michael Questo fallirà se 'arg2' è' 0', 'False' o una sequenza vuota. – marcog

3

Il secondo modo va bene secondo me: è esattamente chiaro quello che fai e per tutti quelli che verranno dopo di te e leggono il codice. Mentre c'è un leggero sovraccarico nel documentare il comportamento predefinito, l'uso di "Nessuno" o di qualsiasi altro per far sì che la funzione generi un valore predefinito è molto comune. Mettere la logica all'interno delle chiamate di funzione non sarebbe certamente encomiabile a mio parere, potrebbe diventare molto complesso molto presto. Quindi lasciatelo nel corpo della funzione, dove si trova tutto il codice.

Problemi correlati