Когда вы передаете параметры в функцию декоратора (например, @check_non_negative(1)
), функция вызывается с этими параметрами, а затем возвращает декоратор, который принимает и возвращает функцию (как если бы вы использовали @validator
без параметры).
Это легче понять с помощью аннотаций типов IMO:
import functools
from typing import cast, Callable, List, TypeVar
_Elem = TypeVar('_Elem')
_Func = TypeVar('_Func', bound=Callable)
def check_non_negative(index: int) -> Callable[[_Func], _Func]:
def validator(f: _Func) -> _Func:
@functools.wraps(f)
def wrap(*args, **kwargs):
if args[index] < 0:
raise ValueError(
'Argument {} must be non negative.'.format(index))
return f(*args, **kwargs)
return cast(_Func, wrap)
return validator
@check_non_negative(1)
def create_list(value: _Elem, size: int) -> List[_Elem]:
return [value]*size
Так что check_non_negative
принимает аргумент int
и возвращает функцию (validator
), которая принимает указать c тип функции (_Func
, которая здесь относится к типу декорированной функции, например create_list
) и возвращает функцию того же типа.