通常不需要关心Python类成员函数中的
self
变量,但我正在实现一个装饰器,看起来像
def extractor(depends: List[Text]=None,
provides: List[Text]=None) -> Callable[[ExtractorFunction],
ExtractorFunction]:
def _func_wrapper(func: ExtractorFunction) -> ExtractorFunction:
func.is_extractor = True # The value is not important through
func.depends = depends
func.provides = provides
@functools.wraps(func)
def _wrapper(self, parsed: CCDATA, target: ExtractResult) -> None:
func(self, parsed, target)
return _wrapper
return _func_wrapper
,其目的是这样使用:
class Extractor():
@extractor()
def _extractor_for_xxx(self, parsed: CCDATA, target: ExtractResult) -> None:
pass
ExtractResult
定义良好,但我不确定如何定义
ExtractorFunction
类型。有任何想法吗?
你可以使用
typing.Protocol
来定义
ExtractorFunction
类型。
Protocol
允许你定义一个结构化的类型,而不需要明确地继承它。这在定义回调函数、装饰器和鸭子类型时特别有用。
from typing import Protocol, List, TypeVar, Callable
from typing_extensions import Self # For Python < 3.11
CCDATA = TypeVar('CCDATA')
ExtractResult = TypeVar('ExtractResult')
class ExtractorFunction(Protocol):
is_extractor: bool
depends: List[str]
provides: List[str]
__call__: Callable[..., None] # 使用省略号(...)表示任意数量的参数
def __call__(self, self: Self, parsed: CCDATA, target: ExtractResult) -> None:
...
def extractor(depends: List[str] = None,
provides: List[str] = None) -> Callable[[ExtractorFunction], ExtractorFunction]:
def _func_wrapper(func: ExtractorFunction) -> ExtractorFunction:
func.is_extractor = True
func.depends = depends or []
func.provides = provides or []
@functools.wraps(func)
def _wrapper(self, parsed: CCDATA, target: ExtractResult) -> None:
func(self, parsed, target)
return _wrapper # type: ignore
return _func_wrapper
在这个例子中,
ExtractorFunction
被定义为一个
Protocol
,它指定了四个属性:
is_extractor
、
depends
、
provides
和
__call__
。
__call__
使用
typing.Callable
来表示它是一个可调用对象,并且使用省略号 (
...
) 来表示它可以接受任意数量和类型的参数。
需要注意的是:
-
我们使用
typing_extensions.Self
来表示__call__
方法中的self
类型。在 Python 3.11 及以后版本中,你可以直接使用typing.Self
。 -
我们在
return _wrapper
后面添加了# type: ignore
,因为 MyPy 目前还不能完全理解Protocol
和装饰器的组合。
使用这个定义,MyPy 就可以检查你的代码,并确保你正确地使用了
extractor
装饰器和
ExtractorFunction
类型。