本文目录导读:

- 使用 try/except 包裹单个协程
- 使用 asyncio.gather() 捕获多个任务的异常
- 使用 asyncio.wait() 分组处理
- 使用 asyncio.TaskGroup(Python 3.11+)
- 使用回调函数添加异常处理
- 全局异常处理器
- 最佳实践建议
在Python中捕获异步任务的异常有几种常见方法,我来详细介绍每种方式:
使用 try/except 包裹单个协程
import asyncio
async def risky_task():
await asyncio.sleep(1)
raise ValueError("出错了!")
async def main():
try:
await risky_task()
except ValueError as e:
print(f"捕获到异常: {e}")
asyncio.run(main())
使用 asyncio.gather() 捕获多个任务的异常
import asyncio
async def task1():
await asyncio.sleep(1)
return "task1完成"
async def task2():
await asyncio.sleep(2)
raise RuntimeError("task2失败了")
async def task3():
await asyncio.sleep(0.5)
return "task3完成"
async def main():
try:
# return_exceptions=False(默认):第一个异常会立即抛出
results = await asyncio.gather(task1(), task2(), task3())
print(f"所有任务完成: {results}")
except RuntimeError as e:
print(f"捕获到异常: {e}")
# 使用 return_exceptions=True 可以获取所有结果和异常
results = await asyncio.gather(
task1(), task2(), task3(),
return_exceptions=True
)
for i, result in enumerate(results):
if isinstance(result, Exception):
print(f"任务{i+1}失败: {result}")
else:
print(f"任务{i+1}成功: {result}")
asyncio.run(main())
使用 asyncio.wait() 分组处理
import asyncio
async def good_task():
await asyncio.sleep(1)
return "成功"
async def bad_task():
await asyncio.sleep(2)
raise ValueError("失败了")
async def main():
tasks = [good_task(), bad_task()]
done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
for task in done:
try:
result = task.result()
print(f"任务成功: {result}")
except Exception as e:
print(f"任务失败: {e}")
# 取消仍在等待的任务
for task in pending:
task.cancel()
asyncio.run(main())
使用 asyncio.TaskGroup(Python 3.11+)
import asyncio
async def task1():
await asyncio.sleep(1)
return "task1完成"
async def task2():
await asyncio.sleep(2)
raise RuntimeError("task2失败")
async def task3():
await asyncio.sleep(0.5)
return "task3完成"
async def main():
try:
async with asyncio.TaskGroup() as tg:
t1 = tg.create_task(task1())
t2 = tg.create_task(task2())
t3 = tg.create_task(task3())
# 如果TaskGroup中没有异常,这里会执行
print("所有任务完成")
print(f"task1结果: {t1.result()}")
print(f"task3结果: {t3.result()}")
except* RuntimeError as e:
print(f"捕获到RuntimeError: {e}")
except* Exception as e:
print(f"捕获到其他异常: {e}")
asyncio.run(main())
使用回调函数添加异常处理
import asyncio
async def risky_task():
await asyncio.sleep(1)
raise TypeError("类型错误")
def handle_exception(future):
try:
future.result()
except Exception as e:
print(f"回调中捕获异常: {e}")
async def main():
task = asyncio.create_task(risky_task())
task.add_done_callback(handle_exception)
# 等待任务完成
try:
await task
except Exception as e:
print(f"主协程中也捕获到: {e}")
asyncio.run(main())
全局异常处理器
import asyncio
import sys
def global_exception_handler(loop, context):
exception = context.get('exception')
message = context.get('message', '未知错误')
if exception:
print(f"全局异常处理: {message}, Exception: {exception}")
else:
print(f"全局异常处理: {message}")
async def bad_task():
await asyncio.sleep(1)
raise ValueError("任务失败")
async def main():
# 设置全局异常处理器
loop = asyncio.get_running_loop()
loop.set_exception_handler(global_exception_handler)
# 创建任务但不等待它(模拟未处理的异常)
asyncio.create_task(bad_task())
await asyncio.sleep(2)
asyncio.run(main())
最佳实践建议
-
对于简单场景:使用
try/except包裹单个await调用 -
多个并行任务:使用
asyncio.gather(return_exceptions=True)获取所有结果 -
Python 3.11+:优先使用
asyncio.TaskGroup,提供更好的异常处理 -
需要精细控制:使用
asyncio.wait()配合FIRST_EXCEPTION等选项 -
复杂应用:设置全局异常处理器来捕获未处理的异常
选择合适的异常处理方式取决于你的具体需求和应用场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播