文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python终止协程和异常处理的方法是什么

2023-07-04 20:16

关注

本文小编为大家详细介绍“python终止协程和异常处理的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“python终止协程和异常处理的方法是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

协程中未处理的异常会向上冒泡,传给 next 函数或 send 方法的调用方(即触发协程的对 象)。

未处理的异常会导致协程终止

"""预激协程的装饰器"""from inspect import getgeneratorstatefrom functools import wrapsdef coroutine(func):    """装饰器:向前执行到第一个`yield`表达式,预激`func`"""    # 把被装饰的生成器函数替换成这里的 primer 函数;    # 调用 primer 函数时,返回预激后的 生成器。    @wraps(func)    def primer(*args, **kwargs):        # 调用被装饰的函数,获取生成器对象。        gen = func(*args, **kwargs)        # 预激生成器。        next(gen)        # 返回生成器。        return gen    return primer@coroutinedef averager():    total = 0.0    count = 0    average = None    while True:        term = yield average        total += term        count += 1        average = total / countif __name__ == '__main__':    coro_avg = averager()    # print(getgeneratorstate(coro_avg))    print(coro_avg.send(10))    print(coro_avg.send(30))    # 发送的值不是数字,导致协程内部有异常抛出。    print(coro_avg.send('spam'))    # 由于在协程内没有处理异常,协程会终止。    # 如果试图重新激活协程,会抛出 StopIteration 异常。    print(coro_avg.send(60))

上面示例,暗示了终止协程的一种方式:发送某个哨符值,让协程退出。内置的 None 和 Ellipsis 等常量经常用作哨符值。Ellipsis 的优点是,数据流中不太常有这个值。我还见 过有人把 StopIteration 类(类本身,而不是实例,也不抛出)作为哨符值;也就是说, 是像这样使用的:my_coro.send(StopIteration)。

从 Python 2.5 开始,客户代码可以在生成器对象上调用两个方法,显式地把异常发给协程。

这两个方法是 throw 和 close。

generator.throw(exc_type[, exc_value[, traceback]])

致使生成器在暂停的 yield 表达式处抛出指定的异常。

如果生成器处理了抛出的异常,代码会向前执行到下一个 yield 表达式,而产出的值会成为调用 generator.throw 方法 得到的返回值。

如果生成器没有处理抛出的异常,异常会向上冒泡,传到调用方的上下 文中。

generator.close()

致使生成器在暂停的yield 表达式处抛出GeneratorExit 异常。

如果生成器没有处 理这个异常,或者抛出了StopIteration 异常(通常是指运行到结尾),调用方不会 报错。

如果收到GeneratorExit 异常,生成器一定不能产出值,否则解释器会抛出 RuntimeError 异常。

生成器抛出的其他异常会向上冒泡,传给调用方。

下面举例说明

如何使用 close 和 throw 方法控制协程:

"""学习在协程中处理异常的测试代码"""from inspect import getgeneratorstateclass DemoException(Exception):    """为这次演示定义的异常类型。"""def demo_exc_handling():    print('-> coroutine started')    try:        while True:            try:                x = yield            #  特别处理 DemoException 异常            except DemoException:                print('*** DemoException handled. Continuing...')            # 如果没有异常,那么显示接收到的值。            else:                print('-> coroutine received: {!r}'.format(x))    finally:        # 如果不管协程如何结束都想做些清理工作,        # 要把协程定义体中相关的代码放入try/ finally 块中        print('-> coroutine ending')if __name__ == '__main__':    exc_coro = demo_exc_handling()    next(exc_coro)    exc_coro.send(11)    exc_coro.send(22)    # 激活和关闭 demo_exc_handling,没有异常    # exc_coro.close()    # 如果把 DemoException 异常传入 demo_exc_handling 协程,    # 它会处理,然后继续运行    # exc_coro.throw(DemoException)    # exc_coro.send(33)    # 如果无法处理传入的异常,协程会终止    exc_coro.throw(ZeroDivisionError)    print(getgeneratorstate(exc_coro))

读到这里,这篇“python终止协程和异常处理的方法是什么”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯