什么是正确的类型提示提示只返回一组特定值的函数?

Cop*_*eld 8 python literals type-hinting python-3.x

我有一个只能返回的函数a,b或者c它们都属于类型,T但是我想将它的一部分签名这个事实,因为它们在函数的上下文中具有特殊含义,我是如何做到的?

目前我用这个

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

那是正确的吗?

我知道我可以做到这一点

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

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

Ces*_*ssa 50

你可以用文字类型来做到这一点。

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"
Run Code Online (Sandbox Code Playgroud)

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

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

蟒蛇 3.8

多亏了PEP 586,将Literal已经包含默认的Python 3.8typing模块。


Blc*_*ght 10

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

但是,您可以创建一个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
Run Code Online (Sandbox Code Playgroud)

这可能有点矫枉过正.只是暗示int作为返回类型(并记录特定值)可能已经足够好了.

  • 我认为这根本不算太过分了.相反,这是静态类型检查的一个好处:您可以指定*exact*函数可以返回的内容.`less`,`equal`和`greater`只是少数`int`值的别名这一事实是一个实现细节.(如果你不想利用`int`类型已经支持的负/零/正分区,那么选择的特定值也无关紧要.) (5认同)
  • @Copperfield你可能想考虑接受Cesar他对文字类型的回答,这似乎是一个新的更好的选择。 (3认同)