使用Python logging模块basicConfig的force参数时出现FileNotFoundError及'FileHandler'无'level'属性异常的问题
使用Python logging模块basicConfig的force参数时出现FileNotFoundError及'FileHandler'无'level'属性异常的问题
看起来你遇到的问题其实根源不是force参数本身,而是路径解析的小坑,咱们一步步拆解来看:
1. 核心错误根源分析
先看报错日志里的关键信息:
E FileNotFoundError: [Errno 2] No such file or directory: 'c:\\Users\\USERNAME\\workbench\\playground\\logging-example\\~\\minimum-reproducible-example.log'
这里的~被当成了当前项目目录下的子文件夹,而不是Windows系统的用户主目录(比如C:\Users\USERNAME)。这是因为Python的标准库(包括logging的FileHandler)不会自动解析~路径,必须手动处理。
至于'FileHandler' object has no attribute 'level'的异常,这是次生错误:因为FileHandler在尝试打开不存在的路径时直接抛出了错误,导致Handler对象没有被完整初始化,后续代码引用这个不完整的对象时就触发了属性不存在的报错。
2. 解决方法:手动解析~路径
你只需要用Python的pathlib或者os模块扩展~路径,把它转换成系统能识别的绝对路径即可,这里提供两种稳妥的方案:
方案一:在测试代码中处理路径
修改tests/test_main.py,用Path.expanduser()解析~:
import logging_example.main from pathlib import Path def test_main() -> None: # arrange # 解析~为用户主目录 log_file_path: str = str(Path("~/minimum-reproducible-example.log").expanduser()) message: str = "Hello, world." # act logging_example.main.main(log_file_path, message) # assert # 注意和logging配置统一编码格式 with open(log_file_path, 'r', encoding='utf-8') as log_file: assert message in log_file.read() return
方案二:在main函数中统一处理路径(更通用)
如果希望无论调用方传入什么路径都能正确解析~,可以在业务代码里提前处理:
import logging from pathlib import Path def main(log_file_path: str, message: str) -> None: # 先解析路径中的~为用户主目录 resolved_log_path = str(Path(log_file_path).expanduser()) logger: logging.Logger = logging.getLogger(__name__) logging.basicConfig( format='%(asctime)s.%(msecs)06d|%(levelname)s|saasapp|%(message)s', datefmt='%Y-%m-%dT%H:%M:%S', encoding='utf-8', level=logging.INFO, filename=resolved_log_path, force=True ) logger.info(message) return
3. 关于force参数的小提醒
force=True本身是没问题的,它的作用是强制重置现有的logging配置(移除所有已存在的Handler和Filter),让basicConfig重新生效。你之前的错误和这个参数无关,只是刚好在使用它的时候触发了路径问题导致的连锁报错。
处理完路径后,你的代码应该就能正常生成日志文件,测试也能顺利通过啦!
备注:内容来源于stack exchange,提问作者Eleanor Holley
相关产品推荐
相关产品推荐

