Python 使用类修饰符Args和KWargs限制函数参数类型
我想要一个易于使用的decorator类,可以用来强制某些参数为预定义类型,以免引发错误。问题是我必须为每个变量指定两次,一次用于每个args,一次用于kwargs。如果原始函数中没有单个splat参数,则即使使用默认参数也是如此 简化:Python 使用类修饰符Args和KWargs限制函数参数类型,python,parameters,Python,Parameters,我想要一个易于使用的decorator类,可以用来强制某些参数为预定义类型,以免引发错误。问题是我必须为每个变量指定两次,一次用于每个args,一次用于kwargs。如果原始函数中没有单个splat参数,则即使使用默认参数也是如此 简化: class ParamConstraint: def __init__(self, *args, error=TypeError, **kwargs): self.args = args self.kwargs = kw
class ParamConstraint:
def __init__(self, *args, error=TypeError, **kwargs):
self.args = args
self.kwargs = kwargs
self.error = error
def __call__(self, function):
def wrap(*args, **kwargs):
for (arg, constraint) in zip(args, self.args):
if not isinstance(arg, constraint):
raise self.error(
"Value '{}' is not of type '{}'.".format(arg, constraint.__name__)
)
for kwarg in self.kwargs:
if kwarg in kwargs:
assert isinstance(kwargs[kwarg], self.kwargs[kwarg])
return function(*args, **kwargs)
return __import__("functools").wraps(function)(wrap)
这很容易使用。假设我想要一个将数字乘以2的函数,但我只想要整数,而不是浮点数。我可以使用:
@ParamConstraint(int)
def foo(x):
return x*2
print(foo(5)) # => prints 10
print(foo(x=5.0)) # => prints 10.0
print(foo(5.0)) # => raises TypeError
现在,我可以通过将位置参数和非位置参数传递到函数中来防止这种情况,但过了一段时间后,它会变得非常乏味。例如,我必须为3个参数写出6个约束:
@ParamConstraint((int, float), int, FunctionType, value=(int, float), count=int, func=FunctionType):
def foo(value, count, func):
for _ in range(count):
value = func(value)
return value
理想情况下,我应该能够通过KWarg传递它,而不提供任何位置参数。但是,这不起作用,因为我无法找出原始函数的位置参数是什么。我很少使用inspect
模块,但没有用
我该怎么补救呢