协程之生成器(协程如何实现的)

网友投稿 215 2022-09-04


协程之生成器(协程如何实现的)

def gen_fun(): #1. 可以产出值, 2. 可以接收值(调用方传递进来的值) html = yield " print(html) yield 3 yield 4 yield 5 return 'sunlong'#1. 生成器不只可以产出值,还可以接收值if __name__ == "__main__": gen = gen_fun() #在调用send发送非none值之前,我们必须启动一次生成器, 方式有两种1. gen.send(None), 2. next(gen) url = gen.send(None) print(url) html = 'sunlong88' #send方法可以传递值进入生成器内部,同时还可以重启生成器执行到下一个yield位置 print(gen.send(html)) print(next(gen)) print(next(gen)) #执行最后一个 找不到数据就会报错 StopIteration: sunlong print(next(gen))

执行结果:

Traceback (most recent call last): File "E:/pythoncode/day07/04.py", line 17, in print(next(gen))StopIteration: sunlonggen_func(): #1. 可以产出值, 2. 可以接收值(调用方传递进来的值) try: yield " except GeneratorExit : pass # raise StopIteration yield 2 yield 3 return "sunlong"if __name__ == "__main__": gen = gen_func() print(next(gen)) gen.close() # print("sunlong88") # print(next(gen))执行结果:(most recent call last): File "E:/pythoncode/day07/04.py", line 22, in gen.close()RuntimeError: generator ignored GeneratorExit

def gen_func(): #1. 可以产出值, 2. 可以接收值(调用方传递进来的值) try: yield " except GeneratorExit : pass # raise StopIteration # yield 2 # yield 3 return "sunlong"if __name__ == "__main__": gen = gen_func() print(next(gen)) gen.close() # print("sunlong88") # print(next(gen))

上述代码中,注释了其他yield  ,再次执行就不会有异常了

gen_func(): #1. 可以产出值, 2. 可以接收值(调用方传递进来的值) try: yield " except GeneratorExit : # pass raise StopIteration yield 2 yield 3 return "sunlong"if __name__ == "__main__": gen = gen_func() print(next(gen)) gen.close() # print("sunlong88") # print(next(gen))

总结close:

#gen.close() 致使生成器在暂停的yield表达式处抛出GeneratorExit异常。如果生成器处没有处理这个异常,或者抛出StopIterration异常(运行到结尾),调用方不会报错。如果收到GeneratorExit异常,生成器一定不能产出值,否则解释器会抛出RuntimeError异常,生成器抛出的其他异常会向上冒泡,传给调用方(要么不要去捕获异常,如果捕获了异常那么那么就请你抛出StopIterration异常(表示已经到了结尾了))

throw:

向生成器抛一个异常:

def gen_func(): #1. 可以产出值, 2. 可以接收值(调用方传递进来的值) yield " yield 2 yield 3 return "bobby"if __name__ == "__main__": gen = gen_func() print(next(gen)) print(gen.throw(Exception, "download error"))执行结果: Exception: download error

改进一下(生成器自己捕获异常):

def gen_func(): #1. 可以产出值, 2. 可以接收值(调用方传递进来的值) try: yield " except Exception as e: pass yield 2 yield 3 return "bobby"if __name__ == "__main__": gen = gen_func() print(next(gen)) print(gen.throw(Exception, "download error"))执行结果: 2

总结:

throw会使生成器在暂停的yield表达式处抛出指定的异常,如果生成器处理了抛出的异常,代码会向前执行到下一个yield表达式。而产生的值会成为调用throw方法得到的返回值,如果生成器没有处理抛出的异常,异常会向上冒泡,传到调用方的上下文中


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:协程之生成器yield from(协程 实现)
下一篇:聊聊mybatis sql的括号问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~