mypy泛型可以将返回序列类型作为参数传递吗?

2024-09-24 22:17:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我想编写以下通用Python代码:

from itertools import chain
from typing import Sequence, Hashable, List, Tuple, Type, TypeVar


SequenceT = TypeVar('SequenceT', bound=Sequence)
HashableT = TypeVar('HashableT', bound=Hashable)


def merge_and_sort_into(seq_type, *iterables):
    # type: (Type[SequenceT], *Iterable[HashableT]) -> SequenceT[HashableT]
    return seq_type(sorted(set(chain(*iterables))))


def merge_and_sort_into_list(*iterables):
    # type: (*Iterable[HashableT]) -> List[HashableT]
    return merge_and_sort_into(list, *iterables)


def merge_and_sort_into_tuple(*iterables):
    # type: (*Iterable[HashableT]) -> Tuple[HashableT]
    return merge_and_sort_into(tuple, *iterables)

代码很好,但是mypy不喜欢merge_and_sort_into()的返回类型,表示error: Type variable "SequenceT" used with arguments。如何将序列类型传递到函数中,并将该类型用作返回类型?(注意:我并没有注意到序列的值类型也需要是可比较/可排序的,但我们忽略这一点)。在

这是mypy将接受的一个版本,但它没有捕获传递到merge_and_sort_into()的类型是其返回类型的约束,因此需要进行强制转换。在

^{pr2}$

Tags: and代码类型returndeftypemergeiterable
1条回答
网友
1楼 · 发布于 2024-09-24 22:17:17

Mypy不支持泛型类型变量,因为它们需要类型系统支持更高的类型,如this comment中所述。在

即使Mypy支持泛型类型变量,原始函数的类型签名也会不正确,因为不是所有的Sequence都可以从iterable构造。例如

class EmptyList(Sequence[T]):
  def __init__(self): pass
  def __getitem__(self, item): raise IndexError
  def __len__(self): return 0

EmptyList([1, 2, 3]) # TypeError

对于特定情况,最直接的解决方案可能是只允许非序列返回类型,并使用Callable而不是{}。在

^{pr2}$

相关问题 更多 >