2013-05-16 20 views
6

Supponiamo che abbia una funzione get_data che richiede un numero di argomenti parola chiave. C'è qualche modo io possa fare questoUtilizzare ** kwargs sia nella chiamata che nella definizione della funzione

def get_data(arg1, **kwargs): 
    print arg1, arg2, arg3, arg4 

arg1 = 1 
data['arg2'] = 2 
data['arg3'] = 3 
data['arg4'] = 4 

get_data(arg1, **data) 

Così l'idea è quella di evitare di digitare i nomi degli argomenti sia in funzione di chiamata e la definizione di funzione. Chiaro la funzione con un dizionario come argomento e le chiavi del dizionario diventano variabili locali della funzione e i loro valori sono i valori del dizionario

Ho provato quanto sopra e ho ricevuto errore dicendo global name 'arg2' is not defined. Comprendo che posso modificare locals() nella definizione di get_data per ottenere il comportamento desiderato.

Quindi il mio codice sarebbe simile a questa

def get_data(arg1, kwargs): 
    locals().update(kwargs) 
    print arg1, arg2, arg3, arg4 

arg1 = 1 
data['arg2'] = 2 
data['arg3'] = 3 
data['arg4'] = 4 

get_data(arg1, data) 

e che non avrebbe funzionato troppo. Inoltre non posso ottenere il comportamento senza utilizzare locals()?

+0

io suggerisco di controllare questa domanda http://stackoverflow.com/questions/3394835/args-and-kwargs –

+2

Non modificare 'locals' , non è nemmeno garantito di lavorare tutto il tempo: http://docs.python.org/2/library/functions.html#locals – jamylak

+1

.. perché dovresti farlo anche tu? Se conosci arg2, arg3, arg4 sono sempre per passare, quindi dovresti specificarli come argomenti singoli. Se non lo fai, anche se hai il comportamento desiderato, non appena hai fatto riferimento diciamo 'arg4' quando' data' non ha definito 'arg4', avrebbe sollevato un NameError, non avrebbe nemmeno stampato alcun dato, avrebbe solo generato un errore. – kampu

risposta

11

**kwargs è un dizionario semplice. Prova questo:

def get_data(arg1, **kwargs): 
    print arg1, kwargs['arg2'], kwargs['arg3'], kwargs['arg4'] 

Inoltre, la documentazione di controllo sulla keyword arguments.

3

Se esaminiamo il tuo esempio:

def get_data(arg1, **kwargs): 
    print arg1, arg2, arg3, arg4 

In namespace tuoi get_data delle funzioni, v'è una variabile denominata arg1, ma non v'è alcuna variabile denominata arg2. quindi non puoi raggiungere una funzione o una variabile che non è nel tuo spazio dei nomi.

Infatti, nel tuo spazio dei nomi; c'è una variabile arg1 e un oggetto dictionary chiamato kwargs. usando la notazione ** prima del kwargs (il nome kwargs non è importante qui, può essere anche qualcos'altro.) dice al compilatore python che kwargs è un dizionario e tutti i valori in quel dizionario saranno valutati come parametri con nome nella definizione della funzione.

consente di dare un'occhiata a questo esempio:

def myFunc(**kwargs): 
    do something 

myFunc(key1='mykey', key2=2) 

quando si chiama myFunc con parametri denominati key1 e key2, i vostri atti di definizione di funzione come

def myFunc(key1=None, key2=None): 

ma con un'eccezione! dal momento che myFunc non ha parametri con nome, il compilatore non sa come gestirli direttamente dal momento che è possibile passare qualsiasi parametro con nome alla propria funzione.

Così la vostra funzione di accettare i parametri con nome all'interno di un dizionario come si chiama la funzione:

myFunc({key1:'mykey', key2:2}) 

così, la vostra definizione di funzione ottenere quei parametri all'interno di un dizionario.**kwargs definisce il dizionario a quel punto, che raccontano anche compilatore che saranno accettate eventuali parametri con nome (con l'aiuto di ** segni prima che i kwargs)

def myFunc(**kwargs): 
    print kwargs 

stamperà

{key1:'mykey', key2:2} 

Quindi nel tuo esempio , puoi usare kwargs come un dizionario;

def myFunc(**kwargs): 
    kwargs['arg2'] 
    kwargs.get('arg3') 

spero che non è complicato (:

Problemi correlati