【问题标题】:How to specify multiple return types using type-hints如何使用类型提示指定多个返回类型
【发布时间】:2016-02-29 22:33:59
【问题描述】:

我在 python 中有一个函数,它可以返回 boollist。有没有办法使用类型提示指定返回类型?

例如,这是正确的做法吗?

def foo(id) -> list or bool:
    ...

【问题讨论】:

  • 你如何得到一个列表或布尔值?
  • @PadraicCunningham 也许实现是我会给你我的ID,你给我一个列表或布尔值:D
  • @PadraicCunningham 多态性。如果您的函数对输入进行检查,无论输入是什么,您都希望在输入一个变量时获得一个布尔值,或者在输入一个变量列表时获得一个布尔值列表。

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


【解决方案1】:

在基础 Python 中只需执行以下操作:

def foo(x: (list, str)):
    pass

【讨论】:

    【解决方案2】:

    来自documentation

    班级typing.Union

    联合类型; Union[X, Y] 表示 X 或 Y。

    因此,表示多个返回数据类型的正确方法是

    from typing import Union
    
    
    def foo(client_id: str) -> Union[list,bool]
    

    但请注意,不强制键入。 Python 仍然是一种动态类型的语言。注释语法的开发是为了在发布到生产环境之前的代码开发过程中提供帮助。正如 PEP 484 所述,“在运行时不会进行类型检查。”

    >>> def foo(a:str) -> list:
    ...     return("Works")
    ... 
    >>> foo(1)
    'Works'
    

    如您所见,我正在传递一个 int 值并返回一个 str。但是__annotations__ 将设置为各自的值。

    >>> foo.__annotations__ 
    {'return': <class 'list'>, 'a': <class 'str'>}
    

    请通过PEP 483 了解有关类型提示的更多信息。另见What are type hints in Python 3.5??

    请注意,这仅适用于 Python 3.5 及更高版本。这在PEP 484 中有明确提及。


    从 Python 3.10 开始,有一种新的方式来表示这个联合。见Union Type

    联合对象保存 | 的值(按位或)对多种类型对象的操作。这些类型主要用于类型注释。与 typing.Union 相比,union 类型表达式支持更简洁的类型提示语法。

    正如我们所见,这与之前版本中的typing.Union 完全相同。我们之前的示例可以修改为使用这种表示法:

    def foo(client_id: str) -> list | bool:
    

    【讨论】:

    • Python 3.4 中是否有等价物
    • @YahyaUddin Nope - PEP 484 :'( .... 仅适用于 Python3.5 以上。
    • @YahyaUddin 非常令人惊讶。你的意思是Function Annotations吗?
    • 所以让我看看我是否得到了这个。 Python 3.4 有函数注解,除了没有强制执行的注解之外什么都不做。但在 Python 3.5 中,这是实际的类型检查。
    • @BhargavRao,对此感到抱歉!我只是觉得离开 cmets 部分太重要了。
    【解决方案3】:

    语句def foo(client_id: str) -&gt; list or bool: 在求值时等价于 def foo(client_id: str) -&gt; list: 因此不会做你想做的事。

    描述“A 或 B”类型提示的原生方式是 Union(感谢 Bhargav Rao):

    def foo(client_id: str) -> Union[list, bool]:
    

    或者,starting with Python 3.10 and beyond,使用 | 运算符:

    def foo(client_id: str) -> list | bool:
    

    我不想成为“你为什么要这样做”的人,但也许有两种返回类型不是你想要的:

    如果您想返回一个布尔值来指示某种类型的特殊错误情况,请考虑改用异常。如果您想返回一个布尔值作为一些特殊值,那么空列表可能是一个很好的表示。 您还可以指示None 可以与Optional[list] 一起返回

    【讨论】:

    • 返回多种类型可能是您想要的用途:例如,如果您需要返回一组子类型中的一个,而不是其他子类型,或者如果您正在尝试处理数据并且想要如果处理不可用,则返回原始表单。此外,如果您要包装遗留代码,它可能非常有用,因为它有助于升级过程和/或看到尴尬的地方。
    • 例外和空列表的想法也很有帮助。谢谢
    • 当我试图表明我允许我的函数返回 strNone(即 -&gt; str | None)时,| 运算符不起作用。在这种情况下,我得到TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'。不过,Union 可以正常工作。
    • 正如 xjcl 在他们的回答中描述的那样,如果是“X 或无”,您也可以使用 Optional[X]
    【解决方案4】:

    如果有人在这里搜索“如何指定多个返回值的类型?”,请使用Tuple[type_value1, ..., type_valueN]

    from typing import Tuple
    
    def f() -> Tuple[dict, str]:
        a = {1: 2}
        b = "hello"
        return a, b
    

    更多信息:How to annotate types of multiple return values?

    【讨论】:

    • 根据文档,这是正确的方法(返回 N 类型):docs.python.org/3/library/typing.html#typing.Tuple;而返回 Union 实际上应该返回 N 个类型值中的一个。
    • 从 Python 3.9 开始,您不需要从类型中导入 Tuple 类。现在它只是 -> tuple[dict, str]
    【解决方案5】:

    Python 3.10(使用|):一个函数的示例,该函数采用intstr 的单个参数并返回intstr

    def func(arg: int | str) -> int | str:
                  ^^^^^^^^^     ^^^^^^^^^ 
                 type of arg   return type
    

    Python 3.5 - 3.9(使用typing.Union):

    from typing import Union
    def func(arg: Union[int, str]) -> Union[int, str]:
                  ^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^^ 
                    type of arg         return type
    

    对于X | None 的特殊情况,您可以使用Optional[X]

    【讨论】:

    • 这个答案对我来说是最有帮助和启发性的。它基本上以非常简洁的形式包含所有其他答案的信息(除了那些建议非多类型替代方案的答案或 cmets)。尽管 OP 没有具体询问多个参数类型,但对如何使用它们以及多个返回类型的描述使答案更加完整。尽管我给出了一个单一类型的示例,但我也很欣赏答案消除了任何混淆(例如我所拥有的),即foo( bar: int )foo( bar ) -&gt; int 之间具体有什么不同(如果有的话)
    • 感谢您的赞美(:我试图给出一个简短而直观的答案
    猜你喜欢
    • 2020-03-30
    • 2017-01-18
    • 1970-01-01
    • 2021-06-15
    • 2023-03-29
    • 2015-11-23
    • 2018-07-20
    • 2019-12-14
    • 2020-02-23
    相关资源
    最近更新 更多