如何定义一个不是类的泛型类型?

2023-12-06

我想定义一个通用类型。就像是:

from typing import TypeVar, Sequence, Union, Generic

T = TypeVar('T')
RecurSeqOf = Sequence[Union[Generic[T], Sequence[T]]]
# mypy error: Variable "typing.Generic" is not valid as a type

有办法做到吗?

整个背景

实际上,我需要一个递归泛型类型,例如

T = TypeVar('T')
RecurSeqOf = Sequence[Union[T, 'RecurSeqOf']]]

但递归类型的定义是尚未支持由 mypy.

这就是为什么我通过将嵌套类型定义设置为有限的深度(例如,通常为 5-6 个级别,但在下面的示例中仅为了简洁起见而设置了两个级别)来解决此问题。 因此,更需要缩短模式,因为我需要将它用于不同的参数类型:

from typing import Sequence, Union, TypeVar, Generic


class A:
    pass


class B:
    pass


# RecurSeqOfA = Sequence[Union[A, 'RecurSeqOfA']]  # mypy error: Cannot resolve name "RecurSeqOfA" (possible cyclic definition)
RecurSeqOfA = Sequence[Union[A, Sequence[Union[A, Sequence[A]]]]]

# RecurSeqOfA = Sequence[Union[A, 'RecurSeqOfA']]  # mypy error: Cannot resolve name "RecurSeqOfA" (possible cyclic definition)
RecurSeqOfB = Sequence[Union[B, Sequence[Union[B, Sequence[B]]]]]

T = TypeVar('T')
# RecurSeqOf = Sequence[Union[Generic[T], 'RecurSeqOf']]  # error: Cannot resolve name "RecurSeqOf" (possible cyclic definition)
# additionally: error: Variable "typing.Generic" is not valid as a type
RecurSeqOf = Sequence[Union[Generic[T], Sequence[Generic[T]]]]  # error: Variable "typing.Generic" is not valid as a type

正如宫城先生的评论所建议的:

from typing import TypeVar, MutableSequence

T = TypeVar('T', bound='RecurSeqOf')
RecurSeqOf = MutableSequence[T]

a: RecurSeqOf[str] = []
a.append("abc")
a.append([])  # mypy error: error: Argument 1 to "append" of "MutableSequence" has incompatible type "List[<nothing>]"; expected "str"
b: RecurSeqOf[str] = []
a.append(b)  # mypy error: Argument 1 to "append" of "MutableSequence" has incompatible type "MutableSequence[str]"; expected "str"
a.append(["cde"])  # mypy error: Argument 1 to "append" of "MutableSequence" has incompatible type "List[str]"; expected "str"

mypy 接受了定义本身。但它并没有达到预期的效果。


Since Sequence已经是通用的,可以直接使用类型变量:

from typing import TypeVar, Sequence, Union

T = TypeVar('T')
# [T, ...] | [[T, ...], ...]
RecurSeqOf = Sequence[Union[T, Sequence[T]]]
# T | [T, ...] | [[T, ...], ...]
RecurSeqOfUnion = Union[RecurSeqOf[T], T]

这是什么文档调用“用户定义的泛型类型别名”。RecurSeqOf = ...定义一个别名,并且Sequence[Union[T, Sequence[T]]]是通用的。


这允许定义固定但任意深度的递归类型:

a0: RecurSeqOf[int]
a1: RecurSeqOf[RecurSeqOfUnion[int]]
a2: RecurSeqOf[RecurSeqOfUnion[RecurSeqOfUnion[int]]]
reveal_type(a0)  # typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]]
reveal_type(a1)  # typing.Sequence[Union[typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int, typing.Sequence[Union[typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int]]]]
reveal_type(a2)  # typing.Sequence[Union[typing.Sequence[Union[typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int, typing.Sequence[Union[typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int]]]], typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int, typing.Sequence[Union[typing.Sequence[Union[typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int, typing.Sequence[Union[typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int]]]], typing.Sequence[Union[builtins.int, typing.Sequence[builtins.int]]], builtins.int]]]]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何定义一个不是类的泛型类型? 的相关文章

随机推荐