python中的编码问题
admin
2023-07-31 01:44:03
0

问题

在平时工作中,遇到了这样的错误:

UnicodeDecodeError: \’ascii\’ codec can\’t decode byte

想必大家也都碰到过,很常见 。于是决定对python的编码做一个整理和学习。

基础知识

在python2.x中,有两种数据类型,unicode和str,这两个都是basestring的子类

>>> a = \'中\'
>>> type(a)

>>> isinstance(a,basestring)
True
>>> a = u\'中\'
>>> type(a)

>>> isinstance(a,basestring)
True

两者的区别,概括来讲,str是字节串,由unicode经过编码(encode)后的字节组成的(好比与python3.x的byte);unicode是对象,才是真正意义上的字符串,由字符组成

>>> a=\'中文\'
>>> len(a)
6
>>> repr(a)
\"\'\\\\xe4\\\\xb8\\\\xad\\\\xe6\\\\x96\\\\x87\'\"
>>> b=u\'中文\'
>>> len(b)
2
>>> repr(b)
\"u\'\\\\u4e2d\\\\u6587\'\"

控制台和脚本

在linux下的python控制台执行以下命令,所得的结果和执行脚本是不同的

>>> a = u\'中文\'
>>> repr(a)
\"u\'\\\\xe4\\\\xb8\\\\xad\\\\xe6\\\\x96\\\\x87\'\"
>>> b = unicode(\'中文\',\'utf-8\')b)
>>> repr(b)
\"u\'\\\\u4e2d\\\\u6587\'\"

可以看到,u\’中文\’初始化的对象a不是我们所期望的,那究竟是什么原因呢?
将python看成是一根管子,管子里头处理的中间过程都是使用unicode的。入口处,全部转成unicode;出口处,再转成目标编码(当然,有例外,处理逻辑中要用到具体编码的情况)。
在控制台执行命令a = u\’中文\’,可以将解释为命令,a = ‘中文’.decode(encode),从而到到unicode对象a。那么这里的encode是什么呢?对于控制台来说,就是标准输入,即sys.stdin.encoding

>>> sys.stdin.encoding
\'ISO-8859-1\'

我的这边控制台默认的编码是ISO-8859-1,故a = u\’中文\’ <=> a = \’中文\’.decode(\’ISO-8859-1\’)
这里的\’中文\’是控制台理解的,即使根据终端编码方式编码后的字节码,对于utf-8编码的终端,\’中文\’=\’\\\\xe4\\\\xb8\\\\xad\\\\xe6\\\\x96\\\\x87\’

>>> a=\'中文\'.decode(\'ISO-8859-1\') 
>>> repr(a)
\"u\'\\\\xe4\\\\xb8\\\\xad\\\\xe6\\\\x96\\\\x87\'\"

那如何修改此编码值呢,设置为什么呢?在linux环境中设置环境变量方法如下,具体设置什么只要与终端编码方式一直即可

export PYTHONIOENCODING=UTF-8

总结

重新回到最初的那个问题,造成问题的原因是没有搞清楚unicode和str的区别,将两者进行了混用。

>>> a = \'中文\'
>>> a.encode(\'gbk\')
Traceback (most recent call last):
  File \"\", line 1, in 
UnicodeDecodeError: \'ascii\' codec can\'t decode byte 0xe4 in position 0: ordinal not in range(128)

以上的对象a其实是str,即字节码,若终端是utf-8编码的话,那么a就是用utf-8 encode的字节码。a.encode(\’gbk\’) 等价于a.decode(encoding).encode(\’gbk\’),即先将字节码解码为unicode字符,然后再encode为字节码。unicode对象作为中转站。那么这里的encoding是什么呢?

>>> import sys
>>> sys.getdefaultencoding()
\'ascii\'

默认是ascii,这正是错误为什么报无法用ascii解码的原因

>>> reload(sys)

>>> sys.setdefaultencoding(\'utf-8\')
>>> a = \'中文\'
>>> repr(a)
\"\'\\\\xe4\\\\xb8\\\\xad\\\\xe6\\\\x96\\\\x87\'\"
>>> a.encode(\'gbk\')
\'\\xd6\\xd0\\xce\\xc4\'

将默认编码改为utf-8,即可。不鼓励对str使用encode方法,因为其中隐式对str进行了解码。decode只对str,encode只对unicode,一切decode/encode都显示指定编码方式。

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...