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

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

问题描述

我梦想着一个带有显式关键字参数的 Python 方法:

def func(a=None, b=None, c=None):for arg, val in magic_arg_dict.items(): # 我从哪里得到魔法?打印 '%s: %s' % (arg, val)

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

<预><代码>>>>功能(b=2)乙:2>>>功能(a=3,c=5)一:3时间:5

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

<预><代码>>>>功能(a=无)答:无

棘手!

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

解决方案

我受到了lost-theory 装饰器优点的启发,在玩了一会儿之后想到了这个:

def actual_kwargs():"""为包装函数提供属性actual_kwargs"的装饰器只包含那些实际传递给函数的关键字参数."""定义装饰器(功能):定义内部(*args,**kwargs):inner.actual_kwargs = kwargs返回函数(*args, **kwargs)返回内部返回装饰器如果 __name__ == "__main__":@actual_kwargs()def func(msg, a=None, b=False, c='', d=0):打印消息对于 arg, val in sorted(func.actual_kwargs.iteritems()):打印 '%s: %s' % (arg, val)func("我只传递一个", a='a')func("这里是 b 和 c", b=True, c='c')func("所有默认值", a=None, b=False, c='', d=0)func("没什么")尝试:func("无效kwarg", e="bogon")除了类型错误,错误:打印 '无效的 kwarg\n %s' % 错误

打印此内容:

<前>我只是通过一个一个:一个这是 b 和 c乙:真的丙:丙所有默认值答:无乙:假的C:d:0没什么无效的夸格func() 得到了一个意外的关键字参数e"

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

嗯,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)

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

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

Tricksy!

Edit: 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

Which prints this:

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'

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.

Mmm, Python is tasty.

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

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