将关键字参数实际传递给Python方法 [英] Getting the keyword arguments actually passed to a Python method

查看:214
本文介绍了将关键字参数实际传递给Python方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我梦见一个带有显式关键字args的Python方法:

I'm dreaming of a Python method with explicit keyword args:

def func(a=None, b=None, c=None):
    for arg, val in magic_arg_dict.items():   # Where do I get the magic?
        print '%s: %s' % (arg, val)

我想得到一个仅包含调用者实际上传递给方法的参数的字典,就像**kwargs一样,但是我不希望调用者能够传递任何旧的随机args,这与**kwargs不同.

I want to get a dictionary of only those arguments the caller actually passed into the method, just like **kwargs, but I don't want the caller to be able to pass any old random args, unlike **kwargs.

>>> func(b=2)
b: 2
>>> func(a=3, c=5)
a: 3
c: 5

所以:有这样的咒语吗?就我而言,我碰巧能够将每个参数与其默认值进行比较以找到不同的参数,但这有点不雅致,当您有9个参数时会变得乏味.对于奖励积分,提供一个咒语,即使调用者传入分配了默认值的关键字参数,该咒语也可以告诉我:

So: is there such an incantation? In my case, I happen to be able to compare each argument against its default to find the ones that are different, but this is kind of inelegant and gets tedious when you have nine arguments. For bonus points, provide an incantation that can tell me even when the caller passes in a keyword argument assigned its default value:

>>> func(a=None)
a: None

棘手!

(词汇)函数签名必须保持不变.它是公共API的一部分,显式关键字args的主要价值在于其文档价值.只是为了使事情变得有趣. :)

The (lexical) function signature has to remain intact. It's part of a public API, and the primary worth of the explicit keyword args lies in their documentary value. Just to make things interesting. :)

推荐答案

我从迷失理论的装饰性优点中得到了启发,在玩了一段时间之后,想到了这个:

I was inspired by lost-theory's decorator goodness, and after playing about with it for a bit came up with this:

def actual_kwargs():
    """
    Decorator that provides the wrapped function with an attribute 'actual_kwargs'
    containing just those keyword arguments actually passed in to the function.
    """
    def decorator(function):
        def inner(*args, **kwargs):
            inner.actual_kwargs = kwargs
            return function(*args, **kwargs)
        return inner
    return decorator


if __name__ == "__main__":

    @actual_kwargs()
    def func(msg, a=None, b=False, c='', d=0):
        print msg
        for arg, val in sorted(func.actual_kwargs.iteritems()):
            print '  %s: %s' % (arg, val)

    func("I'm only passing a", a='a')
    func("Here's b and c", b=True, c='c')
    func("All defaults", a=None, b=False, c='', d=0)
    func("Nothin'")
    try:
        func("Invalid kwarg", e="bogon")
    except TypeError, err:
        print 'Invalid kwarg\n  %s' % err

打印以下内容:


I'm only passing a
  a: a
Here's b and c
  b: True
  c: c
All defaults
  a: None
  b: False
  c: 
  d: 0
Nothin'
Invalid kwarg
  func() got an unexpected keyword argument 'e'

我对此很满意.一种更灵活的方法是将要使用的属性的名称传递给装饰器,而不是将其硬编码为"actual_kwargs",但这是说明解决方案的最简单方法.

I'm happy with this. A more flexible approach is to pass the name of the attribute you want to use to the decorator, instead of hard-coding it to 'actual_kwargs', but this is the simplest approach that illustrates the solution.

嗯,Python很美味.

Mmm, Python is tasty.

这篇关于将关键字参数实际传递给Python方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆