当前位置: 首页 > 知识库问答 >
问题:

键入函数永远不会返回的提示

唐繁
2023-03-14

Python的新类型提示功能允许我们键入函数返回的提示…

def some_func() -> None:
    pass

…或保留未指定的返回类型,PEP规定应导致静态分析器假设任何返回类型都是可能的:

任何没有注释的函数都应被视为具有最通用的类型

但是,我应该如何键入函数永远不会返回的提示?例如,键入 hint 这两个函数的返回值的正确方法是什么?

def loop_forever():
    while True:
        print('This function never returns because it loops forever')

def always_explode():
    raise Exception('This function never returns because it always raises')

既没有指定 -


共有2个答案

李鹏
2023-03-14

2016年7月,这个问题还没有答案(现在有< code > no return ;见新接受答案)。以下是一些原因:

>

  • 当函数不返回时,没有可以分配给类型的返回值(甚至没有)。所以您实际上并不是在尝试注释类型;您正在尝试注释类型的缺失。

    从Python版本3.5开始,提示PEP的类型才刚刚在标准中被采用。此外,PEP只建议类型注释应该是什么样子,同时故意模糊如何使用它们。因此,除了例子之外,没有标准告诉我们如何做任何特别的事情。

    PEP有一段可接受的类型提示,说明了以下内容:

    注释必须是有效的表达式,在定义函数时,其计算不会引发异常(但是参见下面的前向引用)。

    注释应保持简单,否则静态分析工具可能无法解释值。例如,不太可能理解动态计算的类型。(这是一项有意模糊的要求,根据讨论的需要,可能会在本PEP的未来版本中添加特定的包含和排除。)

    因此,它试图阻止您做过于创造性的事情,例如在返回类型提示中抛出异常以表明函数永远不会返回。

    关于例外情况,PEP声明如下:

    没有提出列出明确提出的异常的语法。目前,该特性唯一已知的用例是文档化的,在这种情况下,建议将该信息放在docstring中。

    有一个关于类型注释的建议,其中您有更多的自由,但即使是该部分也没有讨论如何记录类型的缺失。

    在稍微不同的情况下,您可以尝试一件事,当您想要提示某个“正常”函数的参数或返回值应该是永远不会返回的可调用值时。语法是可调用的[[参数类型...]返回类型],因此您可以省略返回类型,如可调用[[ArgTypes...]]中所示。但是,这不符合建议的语法,因此严格来说,它不是可接受的类型提示。打字员可能会窒息。

    结论:你走在时代的前面。这可能令人失望,但对您也有好处:您仍然可以影响如何注释非返回函数。也许这会成为你参与标准化过程的借口。:-)

    我有两个建议。

    >

  • 允许在可调用提示中省略返回类型,并允许转发提示任何内容的类型。这将导致以下语法:

    always_explode: Callable[[]]
    def always_explode():
        raise Exception('This function never returns because it always raises')
    

    引入一个类似Haskell中的底部类型:

    def always_explode() -> ⊥:
        raise Exception('This function never returns because it always raises')
    

    这两项建议可以结合起来。

  • 严子默
    2023-03-14
    匿名用户

    尽管“PEP 484-Type Hints”标准在问题和答案中都提到了,但是没有人引用它的部分:覆盖您的问题的< code>NoReturn类型。

    引用:

    < code>typing模块提供了一个特殊的类型< code>NoReturn,用于注释从不正常返回的函数。例如,无条件引发异常的函数:

    from typing import NoReturn
    
    def stop() -> NoReturn:
        raise RuntimeError('no way')
    

    本节还提供了错误用法的示例。虽然它没有涵盖无限循环的函数,但在类型理论中,它们同样满足从不返回由该特殊类型所表达的含义。

     类似资料:
    • 问题内容: 我试图比较两个相同类型的对象(在dosHave方法中),但是我从未返回过“ true”。这是我的代码: “ Osoba”类如下所示: 来自主代码: 无论我要使用什么输入,这部分都永远不会发生。“ kartoteka”是我当然进口的包裹。每个类都在单独的程序包中,但是使用它们没有问题。我已经尝试了一段时间,但没有任何帮助,似乎 从来都不是真的,但我不知道为什么。没有Boolean.TRU

    • 问题内容: 我正在使用Asp.net MVC3,并尝试在服务器上做一个简单的Ajax发布,它返回部分视图并在搜索过程中更新我的项目列表。 Ajax成功调用服务器,服务器通过发送部分视图进行响应。但是部分视图始终在新页面中呈现。我发现这是因为它不知道即将到来的ajax调用,因此它呈现了一个新页面。 我的控制器代码非常简单: 但是无论如何,Request.IsAjaxRequest()始终返回fals

    • 我目前正在为我的不和谐服务器开发一个discord.py重写(1.3.3)机器人。目前,我正试图让机器人在语音频道中播放音乐。根据discord.py留档,您将使用函数channel.connect()连接到语音通道,该通道将返回VoiceClient对象。 然而,我从未从通道中获得VoiceClient对象。连接()。机器人确实加入了我的频道,但它似乎陷入了一个无限循环。在“wait chann

    • 我得到了一个具有多个EditText-字段的。当我尝试编辑其中一个-字段并单击虚拟键盘上的回车键时,焦点向下转移到下一个-字段,这是我不想发生的事情。我想提交我在第一个-字段中所做的更改,然后关闭键盘。我设法通过在我的. xml文件中添加以下内容来关闭这个焦点转移: 但问题仍然存在,现在更改从未提交,因为我的侦听器从未被调用。如果我在我的中删除除一个项目之外的所有项目,一切都会正常工作。我的中也有

    • 我有一个非常令人沮丧的问题。我正在使用Android摄像头启动摄像头并录制视频。 我期望的是:当我按stop时,我想通过onActivityResult返回我的应用程序活动,以执行一些操作,例如显示视频录制的拇指图像等。 发生的情况:当我按下stop时,屏幕会闪烁,好像回到应用程序,但随后会继续显示摄像头。我在ActivityResult中放了一个日志,它再也不会回这里了!请注意,这不是inten

    • 下面是代码片段,我在其中使用了基于翻滚事件时间的窗口 不幸的是,它似乎从未执行过reduce函数。如果使用上面的代码进行窗口处理,reduce函数可以正常工作。下面是时间戳提取器的代码。30秒水印延迟仅用作测试值,但一分钟翻转窗口为m bd.longValue(),它返回秒时间戳1498658629,因为我的窗口也是以秒为单位定义的。< br >当我使用返回分钟时间戳的bd.longValue()