gpt4 book ai didi

Python mypy 检查 TypeVar(bound=Union[A, B]) 的返回类型不会出错 vs TypeVar(A, B) 会出错

转载 作者:行者123 更新时间:2023-12-03 23:48:06 26 4
gpt4 key购买 nike

我被困在试图理解 TypeVar 的边界上当以两种不同的方式使用它时:

  • Enums = TypeVar("Enums", Enum1, Enum2)
  • Enums = TypeVar("Enums", bound=Union[Enum1, Enum2])

  • 这是我正在使用的代码:

    #!/usr/bin/env python3.6

    """Figuring out why enum is saying incompatible return type."""


    from enum import IntEnum, EnumMeta
    from typing import TypeVar, Union


    class Enum1(IntEnum):

    MEMBER1 = 1
    MEMBER2 = 2


    class Enum2(IntEnum):

    MEMBER3 = 3
    MEMBER4 = 4


    # Enums = TypeVar("Enums", bound=Union[Enum1, Enum2]) # Case 1... Success
    Enums = TypeVar("Enums", Enum1, Enum2) # Case 2... error: Incompatible return value


    def _enum_to_num(val: int, cast_enum: EnumMeta) -> Enums:
    return cast_enum(val)


    def get_some_enum(val: int) -> Enum1:
    return _enum_to_num(val, Enum1)


    def get_another_enum(val: int) -> Enum2:
    return _enum_to_num(val, Enum2) # line 35

    运行时 mypy==0.770 :
  • Case 1 :Success: no issues found
  • Case 2 :35: error: Incompatible return value type (got "Enum1", expected "Enum2")

  • 这个案例与这个问题非常相似: Difference between TypeVar('T', A, B) and TypeVar('T', bound=Union[A, B])

    答案解释了在使用案例 1( bound=Union[Enum1, Enum2] )时,以下是合法的:
  • Union[Enum1, Enum2]
  • Enum1
  • Enum2

  • 当使用 case 2 ( A, B ) 时,以下是合法的:
  • Enum1
  • Enum2


  • 但是,我认为这个答案并不能解释我的问题,我没有使用 Union案件。

    谁能告诉我这是怎么回事?

    最佳答案

    我认为发生错误是因为类型检查器没有足够的信息来通过查看输入参数的类型来推断返回类型。虽然处理可能会有所改善。

    假设您有一个简单的通用函数:

    Enums = TypeVar("Enums", Enum1, Enum2)

    def add(x: Enums, y: Enums) -> Enums:
    return x

    类型检查器可以通过输入参数的类型推断返回类型:
    add(Enum2.MEMBER3, Enum2.MEMBER4) # ok, return Enum2
    add(Enum1.MEMBER1, Enum1.MEMBER2) # ok, return Enum1

    add(Enum2.MEMBER3, Enum1.MEMBER2) # not ok

    看看你的函数 _enum_to_num同样,类型检查器无法推断返回类型,它只是不知道将返回什么类型,因为它不知道 cast_enum 将返回什么类型。 :
    def _enum_to_num(val: int, cast_enum: EnumMeta) -> Enums:
    return cast_enum(val)

    静态类型检查的思想是它在不执行的情况下评估代码,它调查变量的类型,而不是动态值。通过查看 cast_enum的类型,即 EnumMeta ,类型检查器无法判断是否 cast_enum将返回 Enums或不。看起来它只是假设它会返回 Enum1 ,并导致 _enum_to_num(val, Enum2) 中的错误.

    你知道 _enum_to_num(val, Enum2)将返回 Enum2因为你知道 cast_enum 的值是 Enum2 .该值是类型检查器通常不会触及的东西。可能会混淆,变量 cast_enum的值是 Enum2 , 而 cast_enum 的类型是 EnumMeta ,虽然 Enum2是一种类型。

    这个问题可以通过告诉类型检查器类型将通过 cast_enum 来解决。使用 typing.Type :
    from typing import TypeVar, Union, Type

    ...

    def _enum_to_num(val: int, cast_enum: Type[Enums]) -> Enums:
    return cast_enum(val)

    该错误将消失,因为现在类型检查器可以推断返回类型。

    关于Python mypy 检查 TypeVar(bound=Union[A, B]) 的返回类型不会出错 vs TypeVar(A, B) 会出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61335410/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com