实现一个装饰器,用来检查被装饰函数的参数类型。装饰器可以通过参数指明函数参数的类型,调用时如果检测出类型不匹配则抛出异常
@typeassert(str,int,int)
def f(a,b,c):
...
@typeassert(y=list)
def g(x,y):
...
#
提取函数签名:inspect.signature()
带参数的装饰器,也就是根据参数定制化一个装饰器。可以看成生产装饰器的工厂。每次调用typeassert,返回一个特定的装饰器,然后用它去修饰其他函数
def typeassert(*ty_args, **ty_kargs): # 类型断言;参数灵活
def decorator(func): # 真正装饰器函数,接收一个函数参数
def wrapper(*args, **kargs): # 根据typeassert参数定制化一个装饰器,实现wrapper函数
return func(*args, **kargs)
return wrapper
return decorator
# 实现类型检查功能
def typeassert(*ty_args, **ty_kargs):
def decorator(func):
# 获取函数参数和类型的映射关系;func -> a,b
# d = {'a':int,'b':str} ; 通过参数得知
def wrapper(*args, **kargs):
# arg in d, instance(arg, d[arg])
return func(*args, **kargs)
return wrapper
return decorator
# 在py3中,获取函数签名信息
from inspect import signature
def f(a,b,c=1): pass
sig = signature(f)
sig.parameter
a = sig.parameter['a']
a.name # a
a.kind # 位置参数或者是关键字参数
a.default # 默认值
c = sig.parameters['c']
c.deault # 1
bargs = sig.bind(str,int,int) # 数量与参数必保持一致
bargs.arguments['a'] # builtins.str
sig.bind_partial(str) # 只对某些参数做类型要求
#
from inspect import signature
def typeassert(*ty_args, **ty_kargs):
def decorator(func):
sig = signature(func)
btypes = sig.bind_partial(*ty_args, **ty_kargs).arguments
def wrapper(*args, **kargs):
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])
f(1,2,[1,2,3]) # 报错,b必须为str
8.3【装饰器】定义带参数的装饰器
最新推荐文章于 2024-10-02 10:53:34 发布
文章介绍了如何在Python中创建一个装饰器`typeassert`来检查被装饰函数的参数类型。装饰器接受函数参数的类型作为输入,在调用时若发现类型不匹配则抛出异常。通过`inspect.signature`获取函数签名,并结合`bind`方法进行类型验证。
摘要由CSDN通过智能技术生成