2012-12-22 18 views
12

ich eine Python-Klasse mit einer Methode haben, die Argumente und Keyword-Argumente auf diese WeisePython-Funktion * args und ** kwargs zusammen mit anderen spezifischen Schlüsselwort Argumente

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> 

akzeptieren sollte beim Aufruf:

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

ich erhalte den Fehler: TypeError: set_axis() got multiple values for keyword argument 'xlabel'

wie auch immer, wenn ich wie

meine Methode gesetzt
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> 

und rufen:

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

ich SyntaxError: non-keyword arg after keyword arg, wie ich erwartet hatte. Was ist falsch mit dem ersten Fall? Wie sollte ich meiner Methode mitteilen, ein beliebiges Benutzerargument und ein anderes Schlüsselwortargument als die Standardargumente zu akzeptieren? (Hoffe, meine Frage klar genug ist)

+2

Welche Version von Python verwenden Sie? Die erste Klasse, die Sie auflisten, wird in Python 2.7.3 nicht analysiert, weil '* args' durch einen Parameternamen in der' set_axis' Definition gefolgt wird. – phant0m

Antwort

14

Sie würden ein anderes Muster verwenden:

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

Dies Sie * und ** verwenden können, während die Fehlerwerte zu halten, wenn das Schlüsselwort Argumente nicht definiert sind.

+0

Wie? Es ist entweder in Kwargs definiert und liest seinen Wert, oder es verwendet ein Fallback 'x'. –

+4

Ist dies der einzige Weg, dies zu erreichen? Ich habe das Gefühl, dass Sie nicht alle Schlüsselworte in ** kwargs verwenden müssen, um * Argumente und benannte Argumente zu mischen. – eipxen

14

In Python 3 dies funktioniert:

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

Ich benutze Python2.7 – fmonegaglia

+4

Es funktioniert nicht in Python 2.7. – Phob

2

Hier ist eine leichte tweek auf Jure C. Antwort:

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

I get-pop geändert xlabel und ylabel von kwargs falls vorhanden zu entfernen . Ich tat dies, weil der Rest des Codes in der ursprünglichen Frage eine Schleife enthält, die durch alle mit Ausnahme vonxlabel und ylabel iterieren soll.