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

Min-Soo Pipefeet

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

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尚不支持递归类型的定义:https : //github.com/python/mypy/issues/731

这就是为什么我通过使嵌套类型定义达到有限的深度来解决此问题的原因(例如,通常为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接受。但这并没有达到预期的效果。

宫城先生

由于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]]]]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用泛型返回泛型类的类类型?

来自分类Dev

如何为泛型类指定泛型集合类型?

来自分类Dev

如何使用类型的辅助类泛型

来自分类Dev

如何返回泛型类型的类

来自分类Dev

如何从对象类型定义泛型?

来自分类Dev

如何快速定义泛型类的数组

来自分类Dev

如何定义一个泛型方法来返回派生类类型的实例?

来自分类Dev

Spring RestTemplate:如何在泛型类中定义参数类型

来自分类Dev

如何从泛型定义和泛型参数获取泛型类型?

来自分类Dev

如何从泛型定义和泛型参数获取泛型类型?

来自分类Dev

Java泛型:如何为泛型类型化的类指定类类型?

来自分类Dev

Java泛型:如何为泛型类型化的类指定类类型?

来自分类Dev

泛型类的定义:类型边界问题

来自分类Dev

如何在类中使用扩展的泛型类型的类型?

来自分类Dev

Java泛型:定义泛型类时的通配符和类型参数语法

来自分类Dev

泛型类型参数C#-如何泛型类返回类型

来自分类Dev

Scala泛型:如何声明类型必须为case类?

来自分类Dev

如何找出类型是否实现泛型基类

来自分类Dev

如何触发递归更改T类型的泛型类方法?

来自分类Dev

如何创建采用无限类型的泛型类

来自分类Dev

如何遍历类列表并将其用作泛型类型?

来自分类Dev

如何使用“ typeof”从泛型类获取类型?

来自分类Dev

如何在泛型类中处理可为空的类型

来自分类Dev

mixin如何知道泛型超类的类型参数

来自分类Dev

如何找出类型是否实现泛型基类

来自分类Dev

如何从Java中的泛型类型推断类?

来自分类Dev

如何使用泛型类型声明类 - Java 1.7

来自分类Dev

如何模拟接受类类型的泛型方法?

来自分类Dev

在具有泛型类型的类中定义的数据类的类型提示

Related 相关文章

  1. 1

    如何使用泛型返回泛型类的类类型?

  2. 2

    如何为泛型类指定泛型集合类型?

  3. 3

    如何使用类型的辅助类泛型

  4. 4

    如何返回泛型类型的类

  5. 5

    如何从对象类型定义泛型?

  6. 6

    如何快速定义泛型类的数组

  7. 7

    如何定义一个泛型方法来返回派生类类型的实例?

  8. 8

    Spring RestTemplate:如何在泛型类中定义参数类型

  9. 9

    如何从泛型定义和泛型参数获取泛型类型?

  10. 10

    如何从泛型定义和泛型参数获取泛型类型?

  11. 11

    Java泛型:如何为泛型类型化的类指定类类型?

  12. 12

    Java泛型:如何为泛型类型化的类指定类类型?

  13. 13

    泛型类的定义:类型边界问题

  14. 14

    如何在类中使用扩展的泛型类型的类型?

  15. 15

    Java泛型:定义泛型类时的通配符和类型参数语法

  16. 16

    泛型类型参数C#-如何泛型类返回类型

  17. 17

    Scala泛型:如何声明类型必须为case类?

  18. 18

    如何找出类型是否实现泛型基类

  19. 19

    如何触发递归更改T类型的泛型类方法?

  20. 20

    如何创建采用无限类型的泛型类

  21. 21

    如何遍历类列表并将其用作泛型类型?

  22. 22

    如何使用“ typeof”从泛型类获取类型?

  23. 23

    如何在泛型类中处理可为空的类型

  24. 24

    mixin如何知道泛型超类的类型参数

  25. 25

    如何找出类型是否实现泛型基类

  26. 26

    如何从Java中的泛型类型推断类?

  27. 27

    如何使用泛型类型声明类 - Java 1.7

  28. 28

    如何模拟接受类类型的泛型方法?

  29. 29

    在具有泛型类型的类中定义的数据类的类型提示

热门标签

归档