问题描述
启动python时,突然遇到以下错误,报错描述:
C:\Users\starxhong>python
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Failed calling sys.__interactivehook__
Traceback (most recent call last):
File "C:\Python\Python37\lib\site.py", line 439, in register_readline
readline.read_history_file(history)
File "C:\Python\Python37\lib\site-packages\pyreadline\rlmain.py", line 165, in read_history_file
self.mode._history.read_history_file(filename)
File "C:\Python\Python37\lib\site-packages\pyreadline\lineeditor\history.py", line 82, in read_history_file
for line in open(filename, 'r'):
UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 247: illegal multibyte sequence
>>>
分析过程
分析发现,最后报错的位置是C:\Python\Python37\lib\site-packages\pyreadline\lineeditor\history.py的82行,报错类型时UnicodeDecodeError。python中编码错误是比较常见的错误类型,常见的一个错误来源就是中文字符的编码问题,我之前也做过一些总结,有兴趣更细致了解的可以参考:
Python 编码问题——UnicodeDecodeError(一)
Python 编码问题——UnicodeDecodeError(二)。
顺藤摸瓜,可以找到问题发生的源头在C:\Python\Python37\lib\site.py,直接打开看注释,你会知道这个模块有三个主要功能:
- 将site-packages里的第三方库加入系统路径,保证你安装的第三方库可以用import命令找到;
- 引入readline库来实现tab键的自动补全功能,我们之前使用过的python命令都会被存入python_history文件中,readline模块会读取这个文件,来帮助系统做自动补全(类似输入法记录了你曾经输入的词语,然后下次输入就能自动提示);
- 至于第3个功能,引入sitecustomize模块,用于一些本地化配置(比如python文件编码格式),但这个不是必须的,没有加载成功也不会报错。
那么,问题显而易见了:
你曾经某次输入python命令打错成中文,写进了python_history文件,而readline模块的history.py设计的时候就没想过会遇到中文,所以就出现上面的问题,所以要么你把python_history文件中那行中文记录删掉,要么你去改history.py源码加入中文编码。
解决方案
以下方案任选其一,推荐方案2,终身解决:
- 找到python_history文件,将其中的中文记录删除。在我这,该文件存在于C:\Users\starxhong\python_history;
- 打开C:\Python\Python37\lib\site-packages\pyreadline\lineeditor\history.py,修改第82行增加utf-8编码:
for line in open(filename, 'r', encoding='utf-8'):