为何Python asyncio的Task构造函数未被调用?
问题原因及解决方法
核心原因
你修改的是纯Python版的asyncio.tasks.Task类,但CPython 3.11默认使用的是C扩展实现的_asyncio.Task,两者是完全独立的实现,所以你添加的打印语句不会被执行。
CPython为了提升asyncio的运行性能,在3.11版本中默认启用了C版本的Task、Future等核心组件,纯Python版本仅在调试模式或显式指定时才会被调用。
验证方法
在测试脚本中添加一行打印Task类型的代码:
print(type(task))
运行后会输出<class '_asyncio.Task'>,直接证明实际运行的是C扩展实现的Task,而非你修改的纯Python版本。
让修改生效的两种方式
方式1:强制使用纯Python版Task
在代码中显式设置事件循环的任务工厂为纯Python的Task类,覆盖默认的C版本实现:
#create_task.py import asyncio async def coro(sleep): print(f">>> running coro: {sleep} secs<<<") await asyncio.sleep(sleep) print(f">>> finished coro: {sleep} secs<<<") return sleep loop = asyncio.new_event_loop() # 强制指定使用纯Python版Task loop.set_task_factory(asyncio.tasks.Task) task = asyncio.Task(coro(3), loop=loop) print(type(task)) # 此时会输出<class 'asyncio.tasks.Task'> loop.run_until_complete(task)
运行修改后的脚本,就能看到你添加的Task.__init__ called打印内容。
方式2:修改C扩展源码
如果需要修改默认的C版本Task逻辑,需要找到CPython源码中的Modules/_asyncio/tasks.c文件,定位到Task的初始化函数(如task_init),添加对应的打印逻辑后重新编译CPython。
补充说明
注意在CPython 3.11中,asyncio.Task已经是一个工厂函数而非直接的类构造,直接调用asyncio.Task()时,实际返回的实例由当前事件循环的任务工厂决定。
内容的提问来源于stack exchange,提问作者Andres Ariza.
相关产品推荐
相关产品推荐

