仅返回一组特定值的函数的类型提示
Posted
技术标签:
【中文标题】仅返回一组特定值的函数的类型提示【英文标题】:Type hint for a function that returns only a specific set of values 【发布时间】:2017-01-16 19:28:32 【问题描述】:我有一个函数只能返回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
但正如我所说,我想在签名中表示该函数只返回那些特定的值。
【问题讨论】:
为什么不创建这些特定值的枚举,然后指定返回的类型是那个枚举? 【参考方案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
作为返回类型(并记录具体值)可能就足够了。
【讨论】:
我不认为这是矫枉过正。相反,这是静态类型检查的好处之一:您可以确切地指定函数可以返回的内容。less
、equal
和 greater
只是少数 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
解决方案时,我发表了评论。我们在同一页面上。
啊,这很有道理——我没有看到你帖子的原始版本。在这种情况下,你是对的,我们在这里达成一致——为误解道歉:)以上是关于仅返回一组特定值的函数的类型提示的主要内容,如果未能解决你的问题,请参考以下文章