写作背景
承接 上文 ,今天跑程序,偶然发现了一个 bug,就是写入文件的时候报错编码不对,这也是我第一次遇到这个问题,写下这篇博客以提供解决思路。
备注
后来我又将上文中的代码进行了微调,微调后的代码如下:
major_log_path = '主日志'
error_log_path = '记录报错的日志'
logging.basicConfig(
format='%(asctime)s | %(filename)s[line:%(lineno)d] | %(levelname)s | Message: %(message)s',
filename=major_log_path,
filemode='a',
level='INFO'
)
log.logger.logger.handlers = logging.getLogger().handlers
exc_info_logger = logging.getLogger('exc')
exc_info_logger.propagate = False
file_handler = logging.FileHandler(error_log_path)
file_handler.setFormatter(
logging.Formatter(
fmt='%(asctime)s | %(filename)s[line:%(lineno)d] | %(levelname)s | Message: %(message)s'
)
)
exc_info_logger.addHandler(file_handler)
问题分析
既然出现这个问题,那一定是 写入日志内容的时候出错了 ,再一想,只有 FileHandler
会向文件中写入内容,所以我们先看一下 FileHandler
的源码,如下图所示。
可以看到,初始化的时候可以设置 encoding
,即 编码方式 ,那解决办法就是 在实例化 FileHandler
的时候指定编码格式就好了 。即
logging.FileHandler('【日志文件】', encoding='utf-8')
问题再现
设置编码以后,还是报了错,那说明不只是我的代码里明确的 FileHandler
没有指定编码,在我的代码中没有明确体现的地方也还有一个等待我指定编码。那么,最大的可疑之处就在 basicConfig
中。
看一下 basicConfig
的源码,如下图所示。
可以看到,光标处有实例化 FileHandler
的代码。
这里代码的逻辑是:
- 如果
root
没有handler
(确实没有,因为初始化root
的时候就没有,而且代码运行到basicConfig
的时候还未曾向其中添加handler
)就通过传入的参数添加handler
。 - 我传入的参数中没有
handlers
和stream
,但是有filename
,所以会根据我传入的filename
和filemode
实例化FileHandler
。
如果想要指定编码,那就要在这里的 FileHandler
中指定编码。
- 如果想要确定某一种编码,可以修改为:
logging.FileHandler(filename, mode, encoding='【默认编码】')
- 如果想要根据自己的输入改变编码,则修改为:
这时候就可以在设置encoding = kwargs.pop('encoding', '【默认编码】') if filename: h = FileHandler(filename, mode, encoding)
basicConfig
的时候指定编码了。
- 注:默认编码 是要你自己设置一个喜欢的编码,而不是就叫做 “默认编码”,我设置的是
utf-8
。
再次尝试,成功完成任务!!!
结尾
有想要一起学习 python
的小伙伴可以 私信我
进群哦。
以上就是我要分享的内容,因为 学识尚浅,会有不足,还 请各位大佬指正。
有什么问题也可在评论区留言。