【问题标题】:How to use type hint to make sure two variables always have the same type? [duplicate]如何使用类型提示来确保两个变量始终具有相同的类型? [复制]
【发布时间】:2021-11-28 18:49:43
【问题描述】:

我有以下代码

from typing import Union

def add(a: Union[int, str], b: Union[int, str]) -> str:
    return str(a) + str(b)

a: int = 1
b: int = 2
out = add(a, b)  # nice

a: str = 'one'
b: str = 'two'
out = add(a, b)  # nice

a: int = 1
b: str = 'two'
out = add(a, b)  # I hope the static check can raise error here when a and b are different types

我希望mypy 可以为第三种情况引发错误。我该怎么办?

【问题讨论】:

  • 嗯,如果两个变量的类型相同,您可以手动检查函数,简单检查:if type(a) == type(b):
  • 鉴于实施,为什么第三个有问题?另外,为什么返回类型不只是 str?如果您希望 a 和 b 始终具有相同的类型,为什么不使用 genericoverloads
  • 你想要一个类型变量。 from typing import TypeVar,那么你甚至可以约束它,所以你可以做到T = TypeVar("T", str, int)使用def add(a: T, b: T) -> T: ...
  • @Grismar 这个问题是关于 mypy 的,所以它是针对静态分析的

标签: python type-hinting mypy python-typing


【解决方案1】:

一种方法是 @overload 装饰器,它允许您定义可接受的参数的特定组合(将实现定义为更广泛的联合类型):

from typing import Union, overload


@overload
def add(a: int, b: int) -> str:
    pass


@overload
def add(a: str, b: str) -> str:
    pass


def add(a: Union[int, str], b: Union[int, str]) -> str:
    return f"{a}{b}"


add(1, 2)           # nice
add("one", "two")   # nice
add(1, "two")       # error: No overload variant of "add" matches argument types "int", "str"

另一个选项是TypeVar

from typing import TypeVar

A = TypeVar("A", str, int)


def add(a: A, b: A) -> str:
    return f"{a}{b}"


add(1, 2)           # nice
add("one", "two")   # nice
add(1, "two")       # error: Value of type variable "A" of "add" cannot be "object"

这个错误有点神秘——它告诉我们两个参数的最接近的子类型(这是A 需要对应的)是object,并且object 太宽泛而无法满足对A 定义的约束。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多