仅返回一组特定值的函数的类型提示

Posted

技术标签:

【中文标题】仅返回一组特定值的函数的类型提示【英文标题】: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

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

【问题讨论】:

为什么不创建这些特定值的枚举,然后指定返回的类型是那个枚举? 【参考方案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 解决方案时,我发表了评论。我们在同一页面上。 啊,这很有道理——我没有看到你帖子的原始版本。在这种情况下,你是对的,我们在这里达成一致——为误解道歉:)

以上是关于仅返回一组特定值的函数的类型提示的主要内容,如果未能解决你的问题,请参考以下文章

热门模拟具有不同类型返回值的函数?

MySQL返回列包含任何但仅包含一组关键字的所有行

sql 2005 聚合函数

派生类返回值的 PhpStorm 类型提示

R语言每次运行结果返回值的个数为啥不同

Swift初见Swift函数