Python 使用类修饰符Args和KWargs限制函数参数类型

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

我想要一个易于使用的decorator类,可以用来强制某些参数为预定义类型,以免引发错误。问题是我必须为每个变量指定两次,一次用于每个args,一次用于kwargs。如果原始函数中没有单个splat参数,则即使使用默认参数也是如此

简化:

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
模块,但没有用

我该怎么补救呢