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

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,那么可以这样做避免额外调用开销:

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

Python: 收集所有命名参数的更多相关文章

  1. python语言(四)关键字参数、内置函数、导入第三方模块、OS模块、时间模块

    一.可变参数 定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以).此时,可用包裹(packing)位置参数(*args),或者包裹关键字参数(**kwargs),来进行参数传递,会 ...

  2. python matplotlib 中文显示参数设置

    python matplotlib 中文显示参数设置 方法一:每次编写代码时进行参数设置 #coding:utf-8import matplotlib.pyplot as pltplt.rcParam ...

  3. python基础——函数的参数

    python基础——函数的参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复 ...

  4. python中函数的参数解析

    python中函数的各种参数梳理: 1.形参:函数定义时传入的参数 2.实参:函数调用时传入的参数 (有形参必传实参,形参里自身特点可不传的,可传可不传) 3.缺省参数:不传为默认值,传了会覆盖(下面 ...

  5. python类(class)中参数self的解释说明

    python类(class)中参数self的简单解释 1.self只有在类的方法中才会有,其他函数或方法是不必带self的. 2.在调用时不必传入相应的参数.3.在类的方法中(如__init__),第 ...

  6. python 之 函数的参数

    函数的参数好几种类型:包括位置参数.默认参数.可变参数.关键字参数.命名关键字参数. 廖大神python学习笔记,大神网站:百度搜索“廖雪峰的官网” 1.位置参数:调用函数时根据函数定义的参数位置来传 ...

  7. python中函数的参数

    函数参数(一) 思考一个问题,如下: 现在需要定义一个函数,这个函数能够完成2个数的加法运算,并且把结果打印出来,该怎样设计?下面的代码可以吗?有什么缺陷吗? def add2num(): a = 1 ...

  8. Python(函数的参数)

    函数参数的使用 def foo(x,y): pass foo(1,2) 形参:就是变量名 实参:就是变量值 形参:位置形参,默认参数,*args,命名关键字参数,**kwargs 实参: 按位置传值的 ...

  9. Python学习-函数,函数参数,作用域

    一.函数介绍 函数定义:函数时组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 我们已经知道python提供了许多内建函数,print(), type()等.我们也可以自己创建函数,这被叫 ...

随机推荐

  1. H3C ipsec ike 协商配置

    1. 分几步设置 (1)定义ACL (2)创建 ipsec 安全建议 1.选择认证方式 ah 选择 ah头认证方式 不配置 ipsec不能建立成功 (3)创建IKE keychain 可以写多条key ...

  2. io多路复用,select,笔记

    一下代码,是摘自大王的博客,(http://www.cnblogs.com/alex3714/)我自己有加了些注释. 1 2 3 #_*_coding:utf-8_*_ 4 5 __author__ ...

  3. OkHttp使用介绍

    版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4001708.html 为什么需要一个HTTP库 Androi ...

  4. Eclipse 创建Maven项目的问题:a pom xml file already exists in the destination folder

    创建过一个Maven项目,删除的时候只在Eclipse中删除了,但是磁盘上的这个项目没有删除,所以报错 方法:重新创建一个不同名称的Maven项目,右键项目,选择Properties,看你的项目目录( ...

  5. 关于X锁的问题--由select+X锁是否持有到事务结束的误区

    前言:看了宋桑的文章<一次意外的X锁不阻塞问题>,结合本人的测试,说明一下我对select中使用X锁是否会持有到事务结束产生的误区: 详情不多说了,详见宋桑的<一次意外的X锁不阻塞问 ...

  6. elixir 入门笔记

    安装 MAC 平台用 brew 安装 brew update brew install elixir 如果没有 erlang 环境,上面的命令会自定安装 erlang 的环境. 基本数据类型 iex& ...

  7. 扯扯Java中Finalization的意义

    这是Stack Overflow上关于Finalizetion意义的两段讨论,这两个观点是互为补充的. 观点1: 垃圾回收器(The garbage collector)自动在后台运行(虽然它也可以被 ...

  8. 那些年我们一起追过的Linux命令

    1. cd - 作用:返回上次的目录,类似于Windows的后退功能: 2. man ascii 作用:打印出八进制.十六进制和十进制的ASCII码表:(再也不用Google ASCII表啦) 3. ...

  9. mysql悲观锁总结和实践

    使用场景举例:以MySQL InnoDB为例商品t_goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品s ...

  10. HighCharts之2D柱状图

    1.HighCharts之2D柱状图源码 column.html: <!DOCTYPE html> <html> <head> <meta charset=& ...