Python异步任务日志输出至stderr的原因及禁用方法
解决Python异步任务向stderr输出调试信息的问题
你判断得完全没错——这些输出确实是调试/信息级别的日志,不是错误或者警告,大概率是asyncio的内部调试模式被意外开启了。下面给你几个实用的解决办法:
方法1:关闭asyncio的调试模式
这类日志通常是asyncio调试模式启用时才会输出的。你可以在代码启动的地方添加配置来关闭它:
import asyncio # 方式一:重置事件循环策略 asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy()) # 方式二:直接关闭当前循环的调试标志 asyncio.get_event_loop().set_debug(False)
如果你的代码是用asyncio.run()启动的,还可以直接通过参数关闭:
asyncio.run(main(), debug=False)
方法2:通过logging模块过滤低级别日志
要是关闭asyncio调试模式后还有输出,那可能是用到的第三方库(比如日志里出现的aiohttp)在输出调试日志。你可以用Python的logging模块把这些库的日志级别调高,只保留警告及以上的内容:
import logging # 给asyncio和aiohttp设置日志级别为WARNING logging.getLogger("asyncio").setLevel(logging.WARNING) logging.getLogger("aiohttp").setLevel(logging.WARNING)
如果你想临时屏蔽特定代码块的输出,也可以粗暴一点,临时重定向stderr到空设备(仅适用于Linux/macOS):
import os import sys # 先保存原始的stderr original_stderr = sys.stderr try: # 把stderr重定向到/dev/null sys.stderr = open(os.devnull, 'w') # 执行你的异步代码 async for df in sint.FEEDER.upload(pname): if not isinstance(df, pd.DataFrame): raise Exception('internal error: file parser does not returns a dataframe') finally: # 一定要恢复原始stderr sys.stderr.close() sys.stderr = original_stderr
不过这种方法只适合临时用,毕竟会屏蔽这个代码块里所有的stderr输出。
方法3:检查第三方库的内部配置
从日志路径能看到aiohttp的身影,你可以去看看sint.FEEDER.upload()这个方法的内部实现或者文档,说不定它自己开启了调试模式,有没有可以传入的参数来关闭这个功能?比如有些库会有debug=False这类参数可以配置。
内容的提问来源于stack exchange,提问作者attdona
相关产品推荐
相关产品推荐

