【问题标题】:Type hint for a function that returns only a specific set of values仅返回一组特定值的函数的类型提示
【发布时间】:2017-01-16 19:28:32
【问题描述】:

我有一个函数只能返回abc,它们都是T 类型。我想在签名中包含这个事实,因为它们在函数上下文中具有特殊含义。我该怎么做?

目前,我使用这个

def fun(...) -> "a or b or c":
    #briefly explain the meaning of a, b and c in its docstring

那个是正确的吗?

我知道我能做到

def fun(...) -> T:
    # briefly explain the meaning of a, b and c in its docstring

但正如我所说,我想在签名中表示该函数只返回那些特定的值。

【问题讨论】:

  • 为什么不创建这些特定值的枚举,然后指定返回的类型是那个枚举?

标签: python python-3.x type-hinting literals python-typing


【解决方案1】:

您可以通过 literal types 做到这一点。

from typing_extensions import Literal
# from typing import Literal  # Python 3.8 or higher

def fun(b: int) -> Literal["a", "b", "c"]:
    if b == 0:
        return "a"
    if b == 1:
        return "b"
    return "d"

mypy 能够将return "d" 检测为无效语句:

error: Incompatible return value type (got "Literal['d']",
expected "Union[Literal['a'], Literal['b'], Literal['c']]")

Python 3.8

感谢PEP 586,在Python 3.8 typing 模块中Literal 默认为already included

【讨论】:

    【解决方案2】:

    您不能仅使用类型提示来指定您的函数仅返回类型值的子集。顾名思义,类型提示是关于类型而不是值。

    但是,您可以创建一个新的 enum.Enum 子类型,它只包含您要返回的值并在函数中使用它。然后你可以输入提示你正在返回枚举类型。

    import enum
    
    class cmp_results(enum.IntEnum):
        less = -1
        equal = 0
        greater = 1
    
    def my_cmp_function(x, y) -> cmp_results:
        if x < y: return cmp_results.less
        elif x == y: return cmp_results.equal
        else: return cmp_results.greater
    

    这可能有点矫枉过正。只是提示 int 作为返回类型(并记录具体值)可能就足够了。

    【讨论】:

    • 我不认为这是矫枉过正。相反,这是静态类型检查的好处之一:您可以确切地指定函数可以返回的内容。 lessequalgreater 只是少数 int 值的别名,这是一个实现细节。 (如果您不想利用 int 类型已经支持的负/零/正分区,那么选择的特定值也无关紧要。)
    • 这个枚举想法看起来很有趣,而且它还有一个额外的好处,当我调用它的帮助以获得一个很好的文档时,我可以用它做恶作剧来操纵输出
    • @Copperfield 您可能想考虑接受 Cesar 他对文字类型的回答,这似乎是一个新的更好的选择。
    【解决方案3】:

    如果所有都是相同的确切类型,只需 将其添加为返回类型

    def func(...) -> T: # or int or whatever else
    

    我想在签名中表示该函数只返回那些特定的值

    类型提示不指定名称或值,它们只是指定一个类型;类型检查器尝试对提供的 type 进行 act

    如果您只是出于文档目的而这样做,请根据需要添加'a or b or c';用户会理解它,但类型检查器不会而且他们肯定不会对其采取行动。

    【讨论】:

    • 都是T的类型
    • 都是同一类型,例如函数只返回1 or -1 or 0
    • @Jim -- 不幸的是,这不是 PEP 484 类型注释所能做的事情。在 Python 的渐进类型系统(以及大多数类型系统)中,您只能添加注释说明您将返回特定 type 的值——不可能限制输出一种类型的类型系统可以让你这样做(例如dependent types),但PEP 484目前不支持依赖类型。
    • @Michael0x2a 可能你是,当我误解了这个问题并提出了Union 解决方案时,我发表了评论。我们在同一页面上。
    • 啊,这很有道理——我没有看到你帖子的原始版本。在这种情况下,你是对的,我们在这里达成一致——为误解道歉:)
    猜你喜欢
    • 2014-03-06
    • 2020-01-25
    • 2021-02-17
    • 2017-04-03
    • 1970-01-01
    • 2022-01-16
    • 2018-09-08
    • 2021-09-17
    相关资源
    最近更新 更多