#如何为被装饰的函数保存元数据
from functools import update_wrapper,wraps
def mydecorator(func):
def wrapper(*args,**kargs):
print('in wrapper')
func(*arg,**kargs)
update_wrapper(wrapper,func,('__name__','__doc__'),('__dict__',))
return wrapper
@mydecorator
def example():
print('in example')
#如何定义带参数的装饰器
#实现一个装饰器,它用来检查被装饰函数的参数类型,
#装饰器可以通过参数指明函数参数的类型,调用时如果检测出类型不匹配则抛出异常
'''
@typeassert(str,int,int)
def f(a,b,c):
....
@typeassert(y=list)
def g(x,y):
....
'''
#解决方案:提取函数签名:inspect.signature()
#带参数的装饰器,也就是根据参数定制化一个装饰器,可以看成生产装饰器的工厂,
#每次调用typeassert,返回一个特定的装饰器,然后用它去装饰其他函数
from inspect import signature
def typeassert(*ty_args,**ty_kargs):
def decorator(func):
#获取函数参数与类型之间的关系 建立字典
#func->a,b
#d={'a':int,'b':str}
sig=signature(func)
btypes=sig.bind_partial(*ty_args,**ty_kargs).arguments
def wrapper(*args,**kargs):
# arg in d ,istance(arg,d[arg])
for name,obj in sig.bind(*args,**kargs).arguments.items():
if name in btypes:
if not isinstance(obj,btypes[name]):
raise TypeError('"%s" must be "%s"' % (name,btypes[name]))
return func(*args,**kargs)
return wrapper
return decorator
@typeassert(int,str,list)
def f(a,b,c):
print(a,b,c)
f(1,'abc',[1,2,3])
#获取函数的签名
from inspect import signature
def f(a,b,c):
sig=signature(f)
a=sig.parameters['a']
'''
a.name
a.kind
a.default
'''
bargs=sig.bind(str,int,int)
'''
bargs.arguments包含了需要建立的字典
bargs.arguments['a']
'''
sig.bind_partial(str)
如何定义带参数的装饰器PYTHON
猜你喜欢
转载自blog.csdn.net/weixin_38858860/article/details/89108697
今日推荐
周排行