2012-12-22 15 views
12

Ho una classe Python con un metodo che dovrebbe accettare argomenti e argomenti a parola chiave in questo modofunzione Python * args e kwargs ** con altri argomenti chiave specificate

class plot: 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    def set_axis(self, *args, xlabel="x", ylabel="y", **kwargs): 
     for arg in args: 
      <do something> 
     for key in kwargs: 
      <do somethng else> 

al momento della chiamata:

plt = plot(x, y) 
plt.set_axis("test1", "test2", xlabel="new_x", my_kwarg="test3") 

ottengo l'errore: TypeError: set_axis() got multiple values for keyword argument 'xlabel'

Comunque se ho impostato il mio metodo come

class plot: 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    def set_axis(self, xlabel="x", ylabel="y", *args, **kwargs): 
     for arg in args: 
      <do something> 
     for key in kwargs: 
      <do somethng else> 

e chiamare:

plt = plot(x, y) 
plt.set_axis(xlabel="new_x", "test1", "test2", my_kwarg="test3") 

ottengo SyntaxError: non-keyword arg after keyword arg, come mi aspettavo. Cosa c'è di sbagliato nel primo caso? Come dovrei dire al mio metodo di accettare qualsiasi argomento utente e argomento di parole chiave, oltre a quelli predefiniti? (Spero che la mia domanda è abbastanza chiaro)

+2

Quale versione di Python stai usando? La prima classe che hai elencato non viene analizzata in Python 2.7.3 poiché '* args' è sostituito da un nome parametro nella definizione 'set_axis'. – phant0m

risposta

14

Si potrebbe utilizzare un modello diverso:

def set_axis(self, *args, **kwargs): 
    xlabel = kwargs.get('xlabel', 'x') 
    ylabel = kwargs.get('ylabel', 'y') 

Questo consente di utilizzare * e **, mantenendo i valori di ripristino se argomenti chiave non sono definiti.

+0

Come? È definito in kwargs e legge il suo valore, oppure usa un fallback 'x' uno. –

+4

È questo l'unico modo per realizzare questo? Mi sento come se non dovessi tornare ad avere tutti gli argomenti di parole chiave in ** kwargs per mixare * arg e argomenti con nome – eipxen

14

In Python 3 questo funziona:

Python 3.2.3 (default, Oct 19 2012, 19:53:16) 
>>> def set_axis(self, *args, xlabel="x", ylabel="y", **kwargs): 
...  print(args, xlabel, ylabel, kwargs) 
... 
>>> set_axis(None, "test1", "test2", xlabel="new_x", my_kwarg="test3") 
('test1', 'test2') new_x y {'my_kwarg': 'test3'} 
>>> 
+0

Sto usando Python2.7 – fmonegaglia

+4

Non funziona in python 2.7. – Phob

2

Ecco un leggero tweek alla risposta di Jure C.:

def set_axis(self, *args, **kwargs): 
    xlabel = kwargs.pop('xlabel', 'x') 
    ylabel = kwargs.pop('ylabel', 'y') 

ho cambiato get-pop per rimuovere xlabel e ylabel da kwargs se presente . Ho fatto questo perché il resto del codice nella domanda originale contiene un ciclo che intende ripetere tutte le kwargsad eccezione dixlabel e ylabel.

Problemi correlati