2012-09-08 14 views
8

sto imparando a usare argomenti posizionali in pitone e anche cercando di vedere come funzionano quando si confonde con gli argomenti di default: -usando argomenti di default prima di argomenti posizionali

def withPositionalArgs(ae=9,*args): 
    print 'ae= ', ae 
    print 'args = ', args 


a=1 
b=2 
c=[10,20] 

withPositionalArgs(a,b,c) 

Questo mi dà l'output:

ae= 1 
args = (2, [10, 20]) 

come si può vedere, a è considerato un valore passato per ae, e b nonché c sono considerati gli argomenti posizionali.

Così, ora sto cercando di assegnare 10 per ae durante la chiamata withPositionalArgs:

withPositionalArgs(ae=10,b,c) 

Ma, io non posso farlo. Ottengo l'errore:

SyntaxError: non-keyword arg after keyword arg 

La mia domanda è:

Sto facendo in modo corretto? L'argomento predefinito è consentito o una buona pratica da usare prima degli argomenti posizionali nelle funzioni python?

+2

Si potrebbe chiamare con 'withPositionalArgs (10, b, c)'. –

+0

La cosa "sorprendente" è che chiamando ... (1, ae = 2) lancia 'TypeError: ...() ha ottenuto più valori per l'argomento di parole chiave 'ae''. –

risposta

9

In Python2, non è consentito inserire argomenti che hanno un valore predefinito prima degli argomenti posizionali.

Gli argomenti posizionali devono venire prima, quindi gli argomenti con valori predefiniti (o, quando si chiama la funzione, gli argomenti parola chiave), quindi *args e quindi **kwargs.

Questo ordine è necessario per la definizione della funzione e per le chiamate di funzione.

In Python3, l'ordine è stato rilassato. (Ad esempio, *args può precedere un argomento di parola chiave nella definizione della funzione.) See PEP3102.

+0

@unubtu: non è consentito sia nella definizione sia nella chiamata di funzione? O solo a 1 posto? – GodMan

+0

Questo è l'ordine da utilizzare per la definizione e la chiamata di funzione. Però, nella chiamata alla funzione, puoi fare cose come 'pippo (c = 1, ae = 3, b = 2)'. Cioè, l'ordine degli argomenti può essere mescolato fornendo loro argomenti chiave. – unutbu

+0

Può sembrare stupido chiedere, ma, il commento di Vaughn Cato alla mia risposta mi permette di passare l'argomento come richiesto, e python non dà alcun errore. Quindi, devo modificare la tua risposta come: 'In Python, nelle chiamate di funzione, non sei autorizzato a mettere argomenti che hanno un parametro predefinito prima degli argomenti posizionali. Ma ti è permesso farlo nella definizione della funzione? – GodMan

2

Penso che dovremmo fare la distinzione tra i valori di default e il passaggio in argomenti arbitrari/coppie chiave-valore. Il comportamento senza valori di default è la stessa:

def f(ae,*args, **kwargs): 
    print 'ae  = ', ae 
    print 'args = ', args 
    print 'kwargs = ', kwargs 

Il modo in cui abbiamo scritto questo significa che il primo argomento passato in f nella tupla args, che è f(1,2,3,a=1,b=2) (la sequenza va argomenti espliciti, * args, ** kwargs.) Qui: ae = 1, args = (2,3), kwargs = {'a': 1, 'b': 2}.

Se si tenta di passare f(1,2,3,a=1,ae=3), viene generato un TypeError: f() got multiple values for keyword argument 'ae', poiché si tenta di modificare il valore di ae due volte.

.

Un modo per aggirare questo è quello impostato solo ae quando sia esplicitamente prevista, potremmo (dopo la linea DEF):

def g(*args, **kwargs): 
    kwargs, kwargs_temp = {"ae": 9}, kwargs 
    kwargs.update(kwargs_temp) #merge kwargs into default dictionary 

e questa volta g(1,2,3,a=1,ae=3) set args=(1,2,3), kwargs={a=1,ae=3}.

Tuttavia, sospetto che non sia la prassi migliore ...

1

Python3 ha un ordine rilassato.

ora si può fare qualcosa di simile:

def withPositionalArgs(*args, ae=9): 
    print('ae=', ae) 
    print('args =', args) 
a=1 
b=2 
c=[10, 20] 
withPositionalArgs(a, b, c, ae=7) 
Problemi correlati