def gen_fun():
#1. 可以产出值, 2. 可以接收值(调用方传递进来的值)
html = yield "http://projectsedu.com"
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))
执行结果:
1 2 3 4 5 6 7 8 9 10 11 | Traceback (most recent call last): File "E:/pythoncode/day07/04.py" , line 17, in <module> print (next(gen)) StopIteration: sunlong http: //projectsedu.com sunlong88 3 4 5 进程已结束,退出代码1 |
终止协程和异常处理:
close:
def gen_func():
#1. 可以产出值, 2. 可以接收值(调用方传递进来的值)
try:
yield "http://projectsedu.com"
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))
执行结果:
http://projectsedu.com
Traceback (most recent call last):
File "E:/pythoncode/day07/04.py", line 22, in <module>
gen.close()
RuntimeError: generator ignored GeneratorExit
def gen_func():
#1. 可以产出值, 2. 可以接收值(调用方传递进来的值)
try:
yield "http://projectsedu.com"
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 ,再次执行就不会有异常了
1 2 3 | http: //projectsedu.com 进程已结束,退出代码0 |
或者捕获异常,并抛出StopIteration异常(表示已经运行到结尾了),这样也不会有报错
def gen_func():
#1. 可以产出值, 2. 可以接收值(调用方传递进来的值)
try:
yield "http://projectsedu.com"
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 "http://projectsedu.com"
yield 2
yield 3
return "bobby"
if __name__ == "__main__":
gen = gen_func()
print(next(gen))
print(gen.throw(Exception, "download error"))
执行结果:
http://projectsedu.com
Exception: download error
改进一下(生成器自己捕获异常):
def gen_func():
#1. 可以产出值, 2. 可以接收值(调用方传递进来的值)
try:
yield "http://projectsedu.com"
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"))
执行结果:
http://projectsedu.com
2
总结:
throw会使生成器在暂停的yield表达式处抛出指定的异常,如果生成器处理了抛出的异常,
代码会向前执行到下一个yield表达式。而产生的值会成为调用throw方法得到的返回值,如果生成器没有处理抛出的异常,异常会向上冒泡,
传到调用方的上下文中
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/9493981.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能