打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Python: 收集所有命名参数

有时候把Python函数调用的命名参数都收集到一个dict中可以更方便地做参数检查,或者直接由参数创建attribute等。更简单的理解就是def foo(*args, **kwargs): pass可以接受所有的参数,其中kwargs就是命名参数字典,那么直接在函数外面套个foo却不能达到目的,一个比较简单的实现是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def annotation(**annotations):
    """
    A decorator to collect all named args to function.__namedargs__,
    all anonymous args to function.__unnamedargs__,
    decorator's args to function.__annotations__.
    """
    def func_decorator(func):
        @functools.wraps(func)
        def func_wrapper(*args, **kwargs):
            argspec = inspect.getargspec(func)
            namedargs = inspect.getcallargs(func, *args, **kwargs)
            # def foo(a, b=0, *c, **d): pass
            # foo(1, b=2, c=3, d=4) will convert c=3 to namedargs.
            unnamedargs = namedargs.pop(argspec.varargs, ())
            namedargs.update(namedargs.pop(argspec.keywords, {}))
            func_wrapper.__namedargs__ = namedargs
            func_wrapper.__unnamedargs__ = unnamedargs
            func_wrapper.__annotations__ = annotations
            func(*args, **kwargs)
        return func_wrapper
    return func_decorator

annotation的的用法仿照Python 3的Function Annotation,可以对参数做标记等,这里所有的标记都会存放在function.__annotations__中:

如果只要annotation,那么可以这样做避免额外调用开销:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def annotation(**anno):
    """
    A decorator to update decorator's args to function.__annotations__.
    """
    def func_decorator(func):
        """
        Static check annotation.
        """
        argspec = inspect.getargspec(func)
        callargs = set(argspec.args)
        callargs.add(argspec.varargs)
        callargs.add(argspec.keywords)
        invalid_keys = anno.viewkeys() - callargs
        if invalid_keys:
            raise TypeError('Invalid annotation keys = %s' % (invalid_keys))
        else:
            func.__annotations__ = anno
            return func
    return func_decorator
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
python中的组包与解包
01装饰器【Python技巧100例】
Python入门很难?别担心,找对方法!函数基础知识送给你们
《源码探秘 CPython》57. 函数是怎么创建的?
12步轻松搞定python装饰器
python 将传进来的参数动态转为自身成员属性
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服