同时使用可变长度参数和命名参数

2 投票
3 回答
3022 浏览
提问于 2025-04-16 21:43

我需要一些帮助来理解Python中的*args**kwargs。这看起来很简单,但我还是没完全搞明白。这里有一个让我困惑的场景。

我有两个函数,mainfuncwrapperfunc(后者是前者的包装函数)。它们的样子是这样的。

def mainfunc(fname=None, lname=None):
    print 'Firstname: ' + fname
    print 'Lastname: ' + lname

def wrapperfunc(uname, *args):
    print uname
    mainfunc(*args)

我可以这样调用wrapperfunc

wrapperfunc('j.doe', 'john', 'doe')

在这个方法中,所有三个参数都是位置参数。因为j.doe被传给了uname,所以其他两个参数可以通过*args来访问。

但是,我能不能从一个字典中传递一些参数给wrapperfunc,这样我就可以直接在wrapperfunc中访问uname,然后把剩下的位置参数传给mainfunc呢?就像下面这个代码片段:

params = {'uname':'j.doe'}
wrapperfunc(**params, 'john', 'doe')

我想在wrapperfunc中直接访问命名参数,但把所有的位置参数传给mainfunc

3 个回答

1

这可能就是你想要的:

def mainfunc(fname=None, lname=None):
    print 'Firstname: ' + fname
    print 'Lastname: ' + lname

def wrapperfunc(uname, *args, **kwargs):
    print uname
    mainfunc(*args, **kwargs)

然后在Python控制台里

>>> wrapperfunc('j.doe', 'john', lname='doe')
j.doe
Firstname: john
Lastname: doe

这样你就可以同时使用普通参数和关键字参数了。

1

你可以考虑使用装饰器函数。这里有一个来自Python文档的不错例子

这是我对你例子的看法。有没有什么特别的需求是这个不支持的呢?

def wrapper(function):
  def closure(*args, **kwargs):
      print kwargs.get('uname')
      function(*args)
  return closure

@wrapper
def mainFunc(fname, lname):
  print 'Firstname:', fname
  print 'Lastname:', lname

mainFunc('john', 'doe', uname='j.doe')
kw={'uname': 'j.doe_from_dict'}
mainFunc('john', 'doe', **kw)
5

在Python中,关键字参数必须放在位置参数后面。

params = {'uname':'j.doe'}
wrapperfunc('john', 'doe', **params)

这段代码会在两个位置参数之后传递关键字参数,

如果你想查看一个参数,但其他的调用正常进行,可以这样做:

def wrapper(*args, **kwargs):
    print kwargs["uname"]
    return mainfunc(*args, **kwargs)

你可以把这个方法推广到任何你想要的函数,作为一个装饰器使用。

def wrapper(f):
    def wrapped(*args, **kwargs):
        print kwargs["uname"]
        return mainfunc(*args, **kwargs)
    return wrapped

@wrapper
def foo(uname="Test"):
    return uname + "bar"

# the @decorator is equivalent to `foo = wrapper(foo)`

撰写回答