Python函数中的*args和**kwargs与其他指定的关键字参数

14

我有一个Python类,其中有一个方法应该以这种方式接受参数和关键字参数

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中无法解析,因为*argsset_axis定义中后面跟着一个参数名。 - phant0m
3个回答

16

在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'}
>>> 

14

你需要使用不同的模式:

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

这使您能够在保留回退值的同时使用*和**,如果未定义关键字参数,则会使用它们。


怎么做?它要么在kwargs中定义并读取其值,要么使用一个回退的“x”值。 - Jure C.
5
这是实现这个目标的唯一方式吗?我觉得你不应该只能通过在 **kwargs 中使用所有关键字参数来混合 *args 和命名参数。 - eipxen

4
这是对Jure C.答案的微调:
def set_axis(self, *args, **kwargs):
    xlabel = kwargs.pop('xlabel', 'x')
    ylabel = kwargs.pop('ylabel', 'y')

我把get改成了pop,以便在kwargs中删除xlabelylabel。我这样做是因为原问题中的其余代码包含一个循环,该循环旨在遍历除xlabelylabel之外的所有kwargs


救了我的命,我需要在预定义类中添加一个额外的参数。避免了“不是有效的关键字参数”的错误。 - Rolf of Saxony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接