2012-12-22 4 views
12

у меня есть класс Python с методом, который должен принимать аргументы и ключевые аргументы таким образомфункция питон * арг и ** kwargs с другими уточненными именованными аргументами

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> 

при вызове:

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

Я получаю ошибку: TypeError: set_axis() got multiple values for keyword argument 'xlabel'

Во всяком случае, если я изложу свой метод как

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> 

и называют:

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

я SyntaxError: non-keyword arg after keyword arg, как я ожидал. Что не так с первым случаем? Как мне сообщить моему методу принять любой аргумент пользователя и аргумент ключевого слова, отличные от стандартных? (Надеюсь, что мой вопрос достаточно ясно)

+2

Какую версию Python вы используете? Первый класс, который вы перечисляете, не анализируется в Python 2.7.3, потому что '* args' сменяется именем параметра в определении' set_axis'. – phant0m

ответ

14

Вы бы использовать другой шаблон:

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

Это позволяет использовать * и ** при сохранении значения замещающего, если ключевые аргументы не определены.

+0

Как? Он либо определяется в kwargs, и он считывает его значение, либо использует резервный «x». –

+4

Это единственный способ добиться этого? Мне кажется, что вам не нужно возвращаться к тому, чтобы иметь все ключевые слова args в ** kwargs, чтобы смешивать * args и именованные аргументы – eipxen

14

В Python 3 это работает:

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

Я использую Python2.7 – fmonegaglia

+4

Это не работает в python 2.7. – Phob

2

Вот небольшая Твик для ответа JURE С. в:

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

Я изменил get на pop удалить xlabel и ylabel из kwargs, если настоящим , Я сделал это, потому что остальная часть кода в исходном вопросе содержит цикл, который предназначен для итерации по всем kwargsза исключениемxlabel и ylabel.