最直接方式是用 isinstance() 判断事件循环实例类型,但需结合模块名与类名组合检测(如 uvloop.Loop 模块名为 "uvloop",ProactorEventLoop 需先判断 sys.platform == "win32"),并优先使用 asyncio.get_running_loop() 在协程中获取已运行的 loop。

检查 asyncio.get_event_loop() 的具体类型
最直接的方式是获取当前事件循环实例,再用 isinstance() 判断其类。注意不能只比对字符串名或模块路径,因为不同 Python 版本和安装方式下类的导入路径可能不同(比如 uvloop.Loop 和 asyncio.events.AbstractEventLoop 的继承关系稳定,但具体子类名可能变化)。
-
uvloop的事件循环类型通常是uvloop.Loop,需先确保已安装并启用:import uvloop; asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) -
ProactorEventLoop仅在 Windows 上默认启用(Python ≥ 3.8),类型为asyncio.proactor_events.ProactorEventLoop;Linux/macOS 不支持该实现 - 别用
type(loop).__name__做判断——uvloop.Loop在某些打包环境(如 PyInstaller)中可能被重命名或代理
用 loop.__class__.__module__ 和 __name__ 组合判断更可靠
相比单纯依赖 isinstance(),检查模块和类名组合能规避部分 monkey patch 或封装场景(例如某些框架会包装原始 loop)。但依然要小心:uvloop 启用后,asyncio.get_event_loop() 返回的仍是 uvloop.Loop 实例,模块名固定为 "uvloop";而 ProactorEventLoop 模块始终是 "asyncio.proactor_events"。
- 检测 uvloop:
loop.__class__.__module__ == "uvloop" - 检测 ProactorEventLoop:
loop.__class__.__module__ == "asyncio.proactor_events" and loop.__class__.__name__ == "ProactorEventLoop" - 避免只查
__name__ == "ProactorEventLoop"——某些自定义 loop 可能重用这个名字
运行时启用逻辑依赖 asyncio.get_running_loop() 而非 get_event_loop()
在协程内部(尤其是已启动的 event loop 中),应优先用 asyncio.get_running_loop()。它在有运行中 loop 时直接返回,否则抛出 RuntimeError;而 get_event_loop() 在没有显式设置时会自动创建新 loop(可能导致意外行为,比如检测到的是刚新建的默认 SelectorEventLoop)。
- 推荐写法:
try: loop = asyncio.get_running_loop() except RuntimeError: # 当前不在 event loop 中,无法检测 loop = None - 若必须兼容 loop 尚未启动的场景,且你控制着 loop 创建流程,可在启动前记录策略类型(如全局变量
_event_loop_backend = "uvloop")
跨平台判断 ProactorEventLoop 要加操作系统守卫
ProactorEventLoop 是 Windows 专用实现,在 Linux/macOS 上即使手动尝试创建也会失败(抛出 NotImplementedError)。所以任何对它的检测逻辑都应前置 sys.platform == "win32" 判断,否则可能掩盖真实问题。
- 错误示例:
isinstance(asyncio.get_event_loop(), asyncio.proactor_events.ProactorEventLoop)—— 在非 Windows 环境会触发 import 失败或类型不存在 - 正确做法:先
import sys,再if sys.platform == "win32": ...,然后才导入和检查asyncio.proactor_events - uvloop 则无此限制,但需注意:即使安装了 uvloop,未调用
set_event_loop_policy()也不会生效
实际中最容易被忽略的是:检测时机。很多代码在模块顶层或同步函数里调用 get_event_loop(),此时 loop 往往还没真正 run,返回的是未配置的默认实例,导致误判。真要确认运行时所用 loop,必须在协程内、且 loop 已 start 之后执行检测。










