打字模块 - 字符串文字类型

Posted

技术标签:

【中文标题】打字模块 - 字符串文字类型【英文标题】:typing module - String Literal Type [duplicate] 【发布时间】:2017-02-14 10:25:27 【问题描述】:

我正在使用新的 Python 3.5 模块 typing,它很开心。

我想知道如何根据确切的字符串文字指定类型。例如,一个函数保证返回四个字符串之一 - “North”、“West”、“East”、“South - 我们如何将其表示为特定类型变量,而不仅仅是 str

我查看了文档,找到了Union 类型和TypeVar 函数,但找不到答案。

表达此问题的示例函数:

def compute_quadrant(x: int, y: int) -> str:
    if x > 0 and y > 0:
        return 'I'
    elif x < 0 and y > 0:
        return 'II'
    elif x < 0 and y < 0:
        return 'III'
    elif x > 0 and y < 0:
        return 'IV'

我想返回一个更具体的类型,而不是只返回 str,它是四个值之一 - "I""II""III""IV"

在 Typescript 中,可以这样做:type Quadrant = "I" | "II" | "III" | "IV" - 对于这个用例,typing 模块有什么好的 Python 糖吗?

【问题讨论】:

FWIW,有一个 discussion 关于添加仅代表几个特定值的类型。但可以肯定的是,在这种情况下没有必要这样做,因为 enum 非常适合。 【参考方案1】:

忽略您询问的 typing 模块,解决您的问题的一种方法可能是使用多个 cmets 中的 Enum。代码如下所示:

from enum import Enum

class Quadrant(Enum):
    I = 1
    II = 2
    III = 3
    IV = 4

def compute_quadrant(x: int, y: int) -> Quadrant:
    if x > 0 and y > 0:
        return Quadrant.I
    elif x < 0 and y > 0:
        return Quadrant.II
    elif x < 0 and y < 0:
        return Quadrant.III
    elif x > 0 and y < 0:
        return Quadrant.IV
    # return None  # this is what happens without an else clause!

if __name__ == "__main__":
    quad = compute_quadrant(1, -1)
    print(quad, type(quad))              # -> Quadrant.IV <enum 'Quadrant'>
    print(quad.name, type(quad.name))    # -> IV <class 'str'>
    print(quad.value, type(quad.value))  # -> 4 <class 'int'>

如您所见,您可以使用枚举名称和值。名称是您要求的字符串之一。

我在这里看到的一个问题是函数中缺少 else 子句,以及 mypy 当前接受None 作为Quadrant 的有效返回值的行为。这应该手动处理。

【讨论】:

以上是关于打字模块 - 字符串文字类型的主要内容,如果未能解决你的问题,请参考以下文章

打字稿防止将字符串文字泛化为类型

带有鸭子类型对象的打字稿字符串文字

打字稿转换 Object.entries 将派生字符串数组减少为文字类型

ES6 字符串文字/打字稿的 Chrome 开发工具问题

打字机效果文字动画

敲代码指向光标会覆盖下一个字符,无法用空格换行,无法打字或打字会把后面的文字覆盖解决方法