2012-12-22 13 views
12

Mam klasy Pythona z metodą, która powinna przyjąć argumentów i argumentów kluczowych tędyfunkcja python * args i ** kwargs z innymi określonymi argumentami kluczowych

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> 

Dzwoniąc:

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

I pojawia się błąd: TypeError: set_axis() got multiple values for keyword argument 'xlabel'

w każdym razie, jeśli mogę ustawić metodę jak

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> 

i zadzwonić:

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

uzyskać SyntaxError: non-keyword arg after keyword arg, jak się spodziewałem. Co jest nie tak w pierwszym przypadku? Jak mam przekazać mojej metodzie akceptowanie argumentów użytkownika i argumentów słów kluczowych, innych niż domyślne? (Mam nadzieję, że moje pytanie jest wystarczająco jasne)

+2

Jakiej wersji Python używasz? Pierwsza klasa, którą wysyłasz, nie parsuje się w Pythonie 2.7.3, ponieważ po '* args' jest następna nazwa parametru w definicji' set_axis'. – phant0m

Odpowiedz

14

Można by użyć innego wzoru:

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

To pozwala używać * i ** przy zachowaniu wartości zastępczych słów kluczowych, jeśli argumenty nie są zdefiniowane.

+0

Jak? Jest albo zdefiniowany w kwargs i odczytuje jego wartość, albo używa zastępczego "x". –

+4

Czy to jedyny sposób, aby to osiągnąć? Czuję się tak, jakbyś nie musiał powracać do posiadania wszystkich słów kluczowych args w ** kwargs w celu mieszania argumentów * args i nazwanych – eipxen

14

W Pythonie 3 to działa:

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

Używam Python2.7 – fmonegaglia

+4

Nie działa w Pythonie 2.7. – Phob

2

Oto niewielki Tweek do odpowiedzi Jure C. za:

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

Zmieniłem get do pop usunąć xlabel i ylabel od kwargs jeśli obecne . Zrobiłem to, ponieważ reszta kodu w pytaniu oryginalnym zawiera pętlę, która ma na celu iterację wszystkich kwargsz wyjątkiemi ylabel.

Powiązane problemy