如何注释键入。泛型类型本身?

时间:2019-05-18 22:04:05

标签: python python-3.x python-3.6 python-3.7 typing

我正在使用新的Python类型系统,遇到了我不知道如何表达的概念。我想传递通用类类型本身。例如。以描述使用通用 [1] G的函数,键入T并返回G[T]

我使用mypy来检查我的尝试。

天真的方法在Python 3.7中不起作用。

from typing import Generic, Type, List, Mapping, TypeVar

T = TypeVar('T')

def foo(generic: Generic, param: Type[T]) -> Generic[T]: #  error: Invalid type "typing.Generic"
    return generic[param] #  error: Value of type "Generic?[T?]" is not indexable

ListOfInts: Type = foo(List, int)

assert ListOfInts == List[int] # passes in runtime

Python 3.6向typing的反向移植中的天真GenericMeta吗?

backport中提供了GenericMeta,但是我没有找到使用方法,也没有将其用于PEP。

def foo(generic: GenericMeta, param: Type[T]) -> Type[Type[T]]:
    return generic[param] #  error: Value of type "GenericMeta" is not indexable

映射[类型,类型]?

我想出了Mapping,但显然List并非如此。

def apply(generic: Mapping[Type, Type], param: Type[T]) -> Type[Type[T]]:
    return generic[param]

# error: Argument 1 to "apply" has incompatible type "Type[List[Any]]"; expected "Mapping[Type[Any], Type[Any]]"
ListOfInts: Type = apply(List, int)

在Python 3.6和3.7中不太严格

这是我现在使用的版本。 它捕获了apply(10, int)之类的一些荒谬的调用,但是apply(int, int)会经过静态分析并提高运行时间。

def apply(generic: Type, param: Type[T]) -> Type[Type[T]]:
    return generic[param]

所以问题来了,可以表达泛型类型本身吗?

对于我来说,根据鸭子的类型,List应该只是Mapping[Type, Type]。我找到了protocols的PEP,也许这是解决我问题的正确工具?

[1] 如果我理解类别理论的正确性,则该泛型的类型在技术上被命名为functor,并且在Haskell等语言中是众所周知的概念。

0 个答案:

没有答案