欢迎光临!
若无相欠,怎会相见

简单排查 Python Shell 报错 illegal multibyte sequence

序言

最近从 Cmd 打开 Python 一直出现 UnicodeDecodeError 报错,但是刚安装的那会儿是好好的,没有任何报错,因此对这个报错进行一次简单排查。

当前使用的版本信息是: Anaconda 的本体 Python 3.7.7 版本 。

报错信息是 : UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x9a in position 209: illegal multibyte sequence , 即非法的多字节序列

详情

我一般会在 Python 的 Shell 中进行短代码测试,因此会经常在 cmd 中启动 Python。最近一直会报如下错误:

C:\Users\xxxx>python
Python 3.7.7 (default, May  6 2020, 11:45:54) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Warning:
This Python interpreter is in a conda environment, but the environment has
not been activated.  Libraries may fail to load.  To activate this environment
please see https://conda.io/activation
Type "help", "copyright", "credits" or "license" for more information.
Failed calling sys.__interactivehook__
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site.py", line 439, in register_readline
    readline.read_history_file(history)
  File "C:\Anaconda3\lib\site-packages\pyreadline\rlmain.py", line 165, in read_history_file
    self.mode._history.read_history_file(filename)
  File "C:\Anaconda3\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 0x9a in position 209: illegal multibyte sequence
>>>

一般看到 UnicodeDecodeError 就知道是编码问题,但是我想看看是什么导致的这个问题,因此就深究了一下。

看到 Traceback 第一个报错是在 File “C:\Anaconda3\lib\site.py”, line 439, in register_readline 的 readline.read_history_file(history) 函数中,既然有文件及行数,直接到 site.py 文件查找第439行。出问题处的代码如下:

if readline.get_current_history_length() == 0:
            # If no history was loaded, default to .python_history.
            # The guard is necessary to avoid doubling history size at
            # each interpreter exit when readline was already configured
            # through a PYTHONSTARTUP hook, see:
            # http://bugs.python.org/issue5845#msg198636
            history = os.path.join(os.path.expanduser('~'),
                                   '.python_history')
            try:
                readline.read_history_file(history)
            except OSError:
                pass

已知在 try 内部出现错误,就是读取 .python_history 出现的编码错误,现在简单地把history打印出来,然后打开这个文件看看内容

if readline.get_current_history_length() == 0:
            # If no history was loaded, default to .python_history.
            # The guard is necessary to avoid doubling history size at
            # each interpreter exit when readline was already configured
            # through a PYTHONSTARTUP hook, see:
            # http://bugs.python.org/issue5845#msg198636
            history = os.path.join(os.path.expanduser('~'),
                                   '.python_history')
            try:
                print(history)
                readline.read_history_file(history)
            except OSError:
                pass

再次进入Python,看看会是读取哪个文件出现问题,当然从代码中也可以分析出来,但是通过打印方式更简单。

C:\Users\xxxx>python
Python 3.7.7 (default, May  6 2020, 11:45:54) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Warning:
This Python interpreter is in a conda environment, but the environment has
not been activated.  Libraries may fail to load.  To activate this environment
please see https://conda.io/activation
Type "help", "copyright", "credits" or "license" for more information.
C:\Users\xxxx\.python_history
Failed calling sys.__interactivehook__
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site.py", line 440, in register_readline
    readline.read_history_file(history)
  File "C:\Anaconda3\lib\site-packages\pyreadline\rlmain.py", line 165, in read_history_file
    self.mode._history.read_history_file(filename)
  File "C:\Anaconda3\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 0x9a in position 209: illegal multibyte sequence
>>>

定位到 C:\Users\xxxx\.python_history文件,直接打开文件看看到底是什么编码导致的编码错误

import stys
import sys
print(sys.version)
exit()
exit
exit()
import os
os.environ.get('MAIL_USERNAME')
os.environ.get('MAIL_PASSWORD')
exit()
exit
exit()
import os
help(os)
exit
exit()
exit
exit()
exit锛堬級
exit()
exit
exit()

初步判断应该就是第19行的中文字符导致的编码错误,应该是在退出 python 时用的是中文的括号导致,直接把这个删除在试试。

C:\Users\xxxx>python
Python 3.7.7 (default, May  6 2020, 11:45:54) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Warning:
This Python interpreter is in a conda environment, but the environment has
not been activated.  Libraries may fail to load.  To activate this environment
please see https://conda.io/activation
Type "help", "copyright", "credits" or "license" for more information.
C:\Users\xxxx\.python_history
>>>

OK, 问题解决。

总结

.python_history文件应该记录的是在python shell中执行的命令, 而一般来说,基本上所有的编程语言对中文的支持都不是特别好,因此对于出现这个错误,有些理解这个错误出现的原因,ASCII码是全世界一致的,而其他文字就可能出现在不同的编码标准中是相同的情况。

因此在Shell中最好不要使用非ASCII码的字符,在中国,如果采用UTF-8 编码,一般来说是占用3个字节

如有错误,敬请指出,感谢指正!  — 2020-12-20  22:36:42

赞(1) 打赏
转载请注明:飘零博客 » 简单排查 Python Shell 报错 illegal multibyte sequence
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

欢迎光临