如何通过 Python 中的装饰器检查参数和 return 类型
How to check argument and return types via a decorator in Python
我有两个简单的装饰器,它们对函数参数和 return 类型进行基本类型检查。它们单独工作,但不能组合使用。是的,我知道 Python 3.6 中的静态类型检查,但我仍然想让它工作:)
我已经从此处的示例中改编了 Python 2 代码:https://www.python.org/dev/peps/pep-0318/#examples
from functools import wraps
def accepts(*types):
def check_accepts(f):
assert len(types) == f.__code__.co_argcount
@wraps(f)
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
return new_f
return check_accepts
def returns(rtype):
def check_returns(f):
@wraps(f)
def new_f(*args, **kwds):
result = f(*args, **kwds)
assert isinstance(result, rtype), \
"return value %r does not match %s" % (result,rtype)
return result
return new_f
return check_returns
@accepts(int, (int,float))
@returns((int,float))
def func(arg1, arg2):
return arg1 * arg2
我在 assert len(types) == f.__code__.co_argcount
上收到断言错误。
第二个问题,如果可以的话,我如何扩展 @accepts
装饰器来处理 class 方法,这些方法可能有 self
或 cls
参数。
装饰如下:
@returns((int,float))
@accepts(int, (int,float))
def func(arg1, arg2):
return arg1 * arg2
我有两个简单的装饰器,它们对函数参数和 return 类型进行基本类型检查。它们单独工作,但不能组合使用。是的,我知道 Python 3.6 中的静态类型检查,但我仍然想让它工作:)
我已经从此处的示例中改编了 Python 2 代码:https://www.python.org/dev/peps/pep-0318/#examples
from functools import wraps
def accepts(*types):
def check_accepts(f):
assert len(types) == f.__code__.co_argcount
@wraps(f)
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
return new_f
return check_accepts
def returns(rtype):
def check_returns(f):
@wraps(f)
def new_f(*args, **kwds):
result = f(*args, **kwds)
assert isinstance(result, rtype), \
"return value %r does not match %s" % (result,rtype)
return result
return new_f
return check_returns
@accepts(int, (int,float))
@returns((int,float))
def func(arg1, arg2):
return arg1 * arg2
我在 assert len(types) == f.__code__.co_argcount
上收到断言错误。
第二个问题,如果可以的话,我如何扩展 @accepts
装饰器来处理 class 方法,这些方法可能有 self
或 cls
参数。
装饰如下:
@returns((int,float))
@accepts(int, (int,float))
def func(arg1, arg2):
return arg1 * arg2