【发布时间】:2020-10-20 19:42:42
【问题描述】:
我有一个装饰器,它接受一个函数并返回带有一些附加属性的相同函数:
import functools
from typing import *
def decorator(func: Callable) -> Callable:
func.attr1 = "spam"
func.attr2 = "eggs"
return func
如何键入提示decorator 的返回值?我希望类型提示传达两条信息:
- 返回值为
Callable - 返回值有属性
attr1和attr2
如果我写一个协议,
class CallableWithAttrs(Protocol):
attr1: str
attr2: str
然后我输了Callable。显然我不能让协议继承自Callable;
class CallableWithAttrs(Callable, Protocol):
attr1: str
attr2: str
mypy 说:
error: Invalid base class "Callable"
另一方面,如果我只使用Callable,我会丢失有关添加属性的信息。
这在引入类型变量时可能更加复杂,即装饰器必须返回与给定函数 func 相同类型的可调用对象,正如 MisterMiyagi 在 cmets 中指出的那样。
import functools
from typing import *
C = TypeVar('C', bound=Callable)
def decorator(func: C) -> C:
func.attr1 = "spam"
func.attr2 = "eggs"
return func
现在我该怎么办?我不能从类型变量继承:
class CallableWithAttrs(C, Protocol):
attr1: str
attr2: str
error: Invalid base class "C"
【问题讨论】:
-
Union[CallableWithAttrs, Callable]…? -
@deceze 更像
Intersection[CallableWithAttrs, Callable](which doesn't exist). -
是的,确实如此。
-
从您的
decorator的角度来看,func是Callable为什么重要?它从来没有这样称呼它,在鸭子打字之后,我看不出有理由“人为地”将其范围限制为Callableobjects(?) -
@PiCTo 在语法上对装饰器来说可能无关紧要,但在语义上确实很重要,即根据装饰器的规范。这个装饰器只能与
Callables 一起使用。 (这里的例子只是一个最小的例子。)
标签: python type-hinting python-typing