Python 为只返回一组特定值的函数键入提示

Python 为只返回一组特定值的函数键入提示,python,python-3.x,literals,type-hinting,Python,Python 3.x,Literals,Type Hinting,我有一个函数只能返回a、b或c,它们都是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 a

我有一个函数只能返回
a
b
c
,它们都是
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

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

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

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

类型提示不指定名称或值,只指定类型;类型检查器尝试对提供的类型执行操作


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

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

但是,您可以创建一个新的
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
导入枚举
类别cmp_结果(内部枚举):
减=-1
相等=0
更大=1
定义my_cmp_函数(x,y)->cmp_结果:
如果x
这可能太过分了。仅仅暗示
int
作为返回类型(并记录具体值)可能就足够了。

您可以使用。
从键入扩展导入文字
#输入import Literal#Python 3.8或更高版本
def-fun(b:int)->Literal[“a”、“b”、“c”]:
如果b==0:
返回“a”
如果b==1:
返回“b”
返回“d”
mypy能够将
返回“d”
检测为无效语句:

error: Incompatible return value type (got "Literal['d']",
expected "Union[Literal['a'], Literal['b'], Literal['c']]")
Python 3.8
多亏了,Python3.8
键入模块中默认使用
文本

它们都是
T
类型,都是相同的类型,例如,函数只返回
1
-1
0
@Jim——不幸的是,这与PEP 484类型注释无关。在Python的渐进式类型系统(以及大多数类型系统)中,只能添加注释,说明将返回特定类型的值——不可能限制类型的输出值。有一些类型系统允许您这样做(例如),但PEP 484目前不支持依赖类型。@Michael0x2a您可能是,我的评论是在我误解了这个问题并提出了一个
Union
解决方案时发表的。我们在同一页。啊,这是有道理的——我没有看到你文章的原始版本。在这种情况下,您是对的,我们在这里达成了一致--为误解道歉:)为什么不创建这些特定值的枚举,然后指定返回类型是该枚举?我认为这一点也不过分。相反,这是静态类型检查的好处之一:您可以精确地指定函数可以返回什么。
less
equal
greater
只是少数
int
值的别名,这是一个实现细节。(如果您不想利用
int
类型已经支持的负/零/正分区,那么选择的特定值也无关紧要。)这个枚举想法看起来很有趣,它还有一个额外的好处,就是我可以用它来做一些恶作剧,在调用帮助时操纵输出documentation@Copperfield你可能想考虑用文字类型来接受Cesar的回答,这似乎是一个新的更好的选择。
error: Incompatible return value type (got "Literal['d']",
expected "Union[Literal['a'], Literal['b'], Literal['c']]")