如何捕获Python logging模块的返回状态或抛出的异常?
解决Python Logging写入Unicode字符串的编码问题
我懂你遇到的麻烦了——当你尝试把包含Unicode字符(比如示例里的Δ)的字符串写入日志文件时,程序触发了异常进入except块,对吧?这其实是因为logging.basicConfig默认使用系统的本地编码(比如Windows环境下通常是GBK),而像Δ这类Unicode字符不在GBK的编码范围内,所以写入时会抛出编码错误。
问题原因拆解
默认情况下,logging模块调用basicConfig创建文件处理器时,会采用操作系统的默认编码打开文件。如果你的字符串包含超出该编码范围的Unicode字符,就会触发UnicodeEncodeError,导致程序进入异常处理块。
解决方案
下面给你几种靠谱的解决办法,按推荐程度排序:
方法一:Python 3.9+ 直接指定编码参数
从Python 3.9开始,logging.basicConfig新增了encoding参数,直接指定文件编码为UTF-8就能完美支持所有Unicode字符:
import logging # 新增encoding='utf-8'参数 logging.basicConfig( filename='ReviewReport.log', filemode='w', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', encoding='utf-8' ) myTestStr = 'My Str is DeltaΔ' try: logging.info(myTestStr) except Exception as e: print(f'In except block.... 错误信息: {e}') print('execute rest of the program')
这种方法最简单直接,只要你的Python版本符合要求,优先用它。
方法二:兼容所有Python版本的手动配置
如果你的Python版本低于3.9,就需要手动创建FileHandler并指定编码,这种方式兼容性拉满:
import logging # 初始化logger对象 logger = logging.getLogger() logger.setLevel(logging.INFO) # 创建FileHandler时明确指定encoding='utf-8' file_handler = logging.FileHandler( 'ReviewReport.log', mode='w', encoding='utf-8' ) # 设置日志格式 formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) # 将处理器添加到logger logger.addHandler(file_handler) myTestStr = 'My Str is DeltaΔ' try: logger.info(myTestStr) except Exception as e: print(f'In except block.... 错误信息: {e}') print('execute rest of the program')
这种方式虽然代码多一点,但不管你用的是Python 3.6还是更早的版本,都能正常工作。
方法三:异常块内手动处理编码(不推荐)
如果不想修改logging的全局配置,也可以在异常块里手动编码后写入日志,但这种方法比较繁琐,只适合临时应急:
import logging logging.basicConfig(filename='ReviewReport.log', filemode='w', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') myTestStr = 'My Str is DeltaΔ' try: logging.info(myTestStr) except Exception as e: print(f'In except block.... 错误信息: {e}') # 手动构造日志内容并以UTF-8编码写入 log_content = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s').format( logging.LogRecord("", logging.INFO, "", 0, myTestStr, None, None) ) with open('ReviewReport.log', 'a', encoding='utf-8') as f: f.write(log_content + '\n') print('execute rest of the program')
这种方法不推荐长期使用,因为会破坏logging模块的统一配置,维护起来麻烦。
内容的提问来源于stack exchange,提问作者Jay Prakash Singh
相关产品推荐
相关产品推荐

