我想静态地强制类的方法返回包装在某种抽象类型中的值,而我对此一无所知:
例如给定抽象类
F = ???
class ThingF(Generic[F]):
@abstractmethod
def action(self) -> F[Foo]:
...
我希望能够静态检查这是否无效:
class ThingI(ThingF[List]):
def action(self) -> Foo:
...
因为action
不返回List[Foo]
。
但是上述ThingF
的声明甚至都没有运行,因为Generic
期望它的参数是类型变量,而我无法找到一种方法来使F
成为类型变量“孔”。
两者
F = TypeVar('F')
和
T = TypeVar('T')
F = Generic[T]
不起作用,因为TypeVar
不可下标,或者Generic[~T]
不能用作类型变量。
如果需要的话,我基本上想要的是一个“更高种类的类型变量”,它是类型构造函数的抽象。即上面写着“ F可以是采用另一种类型来产生具体类型的任何类型”。
有什么方法可以使用Python的类型注释来表达它,并用mypy
对其进行静态检查?
答案 0 :(得分:1)
不幸的是,类型系统(如PEP 484中所述)不支持更高类型的类型-这里有一些相关的讨论:https://github.com/python/typing/issues/548。
mypy和其他类型检查工具可能会在将来的某个时候获得它们的支持,但我不会屏住呼吸。要实现这一目标,需要进行一些相当复杂的实施工作。
答案 1 :(得分:1)
您可以对dry-python/returns
使用高级类型。
我们同时提供了原语和自定义mypy
插件,以使其正常工作。
以下是Mappable
或Functor
的示例:
from typing import Callable, TypeVar
from returns.interfaces.mappable import MappableN
from returns.primitives.hkt import Kinded, KindN, kinded
_FirstType = TypeVar('_FirstType')
_SecondType = TypeVar('_SecondType')
_ThirdType = TypeVar('_ThirdType')
_UpdatedType = TypeVar('_UpdatedType')
_MappableKind = TypeVar('_MappableKind', bound=MappableN)
@kinded
def map_(
container: KindN[_MappableKind, _FirstType, _SecondType, _ThirdType],
function: Callable[[_FirstType], _UpdatedType],
) -> KindN[_MappableKind, _UpdatedType, _SecondType, _ThirdType]:
return container.map(function)
它将适用于任何Mappable
,examples:
from returns.maybe import Maybe
def test(arg: float) -> int:
...
reveal_type(map_(Maybe.from_value(1.5), test)) # N: Revealed type is 'returns.maybe.Maybe[builtins.int]'
并且:
from returns.result import Result
def test(arg: float) -> int:
...
x: Result[float, str]
reveal_type(map_(x, test)) # N: Revealed type is 'returns.result.Result[builtins.int, builtins.str]'
它肯定有一些限制,例如:它仅适用于直接的Kind
子类型,并且我们需要单独的别名Kind1
,Kind2
,Kind3
等。因为当时mypy
不支持可变参数泛型。
来源:https://github.com/dry-python/returns/blob/master/returns/primitives/hkt.py 插件:https://github.com/dry-python/returns/blob/master/returns/contrib/mypy/_features/kind.py
文档:https://returns.readthedocs.io/en/latest/pages/hkt.html
公告帖子:https://sobolevn.me/2020/10/higher-kinded-types-in-python