我一直在尝试使用Python中的不同类型的装饰器,我发现很难理解参数化的装饰器。装饰器接受callable并返回callable(在我的例子中,callable是一个函数),代码如下:
def check_non_negative(index):
def validator(f):
def wrap(*args):
if args[index]<0:
raise ValueError(
'Argument {} must be non negative.'.format(index))
return f(*args)
return wrap
return validator
@check_non_negative(1)
def create_list(value,size):
return [value]*size
create_list('a',3)我在这里看到,根据定义,check_non_negative不是装饰器,但它的行为类似于装饰器(在运行期间,验证器是实际的装饰器)。check_non_negative接受一个整数,而不是可调用的,但它的行为就像装饰器。有人能解释一下原因吗?
发布于 2020-04-16 00:22:08
根据您的定义,从技术上讲,check_non_negative不是一个装饰器,可以称之为“装饰器工厂”。它返回validator,这是一个装饰器。
基本上,只要你有:
@<expression>
def ...然后<expression>必须计算为装饰器,即接受单个参数的callable,该参数也是callable。
发布于 2020-04-16 00:29:47
当您将参数传递给装饰器函数(即@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),该函数接受特定类型的函数(_Func,这里指的是修饰函数的类型,例如create_list),并返回相同类型的函数。
https://stackoverflow.com/questions/61233508
复制相似问题