zoukankan      html  css  js  c++  java
  • Python: 收集所有命名参数

    有时候把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__中:

    image

    如果只要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
  • 相关阅读:
    1024 Calendar Game
    外存管理与文件系统(1)
    1008 Gnome Tetravex
    写给想用技术改变世界的年轻人by 沃兹
    为什么VS2008里没有Silverlight呢?
    QQ消息群发器实现原理及核心代码
    JavaScript检测多组Radio是否选择
    C#操作Excel(导入导出)
    String.Split 方法有6个重载函数:
    【原】Ext2.2学习系列:ExtJS与.NET结合开发实例全部Ext2.2示例索引贴 (共收录56篇文章)
  • 原文地址:https://www.cnblogs.com/codingmylife/p/3640668.html
Copyright © 2011-2022 走看看