UnicodeDecodeError—UTF-8 编码(Python 中的底层基础)

常见的字符编码有 ASCII 编码, GBK 编码, Unicode 编码和 UTF-8 编码等等。这里,我们主要 介绍 ASCII 、 Unicode 和 UTF-8。

3.1 ASCII 编码

计算机是在美国诞生的,人家用的是英语,而在英语的世界里,不过就是英文字母,数字和一些普通符 号的组合而已。

在 20 世纪 60 年代,美国制定了一套字符编码方案,规定了英文字母,数字和一些普通符号跟二进 制的转换关系,被称为 ASCII (American Standard Code for Information

Interchange ,美国信息互换标准编码 ) 码。

比如,大写英文字母 A 的二进制表示是 01000001 (十进制 65 ),小写英文字母 a 的二进制表示 是 01100001 (十进制 97 ),空格 SPACE 的二进制表示是 00100000 (十进制 32 )。

3.2 Unicode 编码

ASCII 码只规定了 128 个字符的编码,这在美国是够用的。可是,计算机后来传到了欧洲,亚洲, 乃至世界各地,而世界各国的语言几乎是完全不一样的,用 ASCII 码来表示其他语言是远远不够的, 所以,不同的国家和地区又制定了自己的编码方案,比如中国大陆的 GB2312 编码 和 GBK 编码等, 日本的 Shift_JIS 编码等等。虽然各个国家和地区可以制定自己的编码方案,但不同国家和地区的计算机在数据传输的过程中就会出 现各种各样的乱码(mojibake ),这无疑是个灾难。

怎么办?想法也很简单,就是将全世界所有的语言统一成一套编码方案,这套编码方案就叫

Unicode ,它为每种语言的每个字符设定了独一无二的二进制编码,这样就可以跨语言,跨平台进行文 本处理了,是不是很棒!

Unicode 1.0 版诞生于 1991 年 10 月,至今它仍在不断增修,每个新版本都会加入更多新的字 符,目前最新的版本为 2016 年 6 月 21 日公布的 9.0.0 。

Unicode 标准使用十六进制数字,而且在数字前面加上前缀 U+ ,比如,大写字母「 A 」的

unicode 编码为 U+0041 ,汉字「严」的 unicode 编码为 U+4E25 。更多的符号对应表,可

以查询 unicode.org ,或者专门的 汉字对应表 。

3.3 UTF-8编码

Unicode 看起来已经很完美了,实现了大一统。但是, Unicode 却存在一个很大的问题:资源浪费。为什么这么说呢?原来,Unicode 为了能表示世界各国所有文字,一开始用两个字节,后来发现两个 字节不够用,又用了四个字节。比如,汉字「严」的 unicode 编码是十六进制数 4E25 ,转换成 二进制有十五位,即 100111000100101 ,因此至少需要两个字节才能表示这个汉字,但是对于其他 的字符,就可能需要三个或四个字节,甚至更多。

这时,问题就来了,如果以前的 ASCII 字符集也用这种方式来表示,那岂不是很浪费存储空间。比 如,大写字母「A 」的二进制编码为 01000001 ,它只需要一个字节就够了,如果 unicode 统一使用 三个字节或四个字节来表示字符,那「A 」的二进制编码的前面几个字节就都是 0 ,这是很浪费存 储空间的。

为了解决这个问题,在 Unicode 的基础上,人们实现了 UTF-16, UTF-32 和 UTF-8 。下面只说 一下 UTF-8 。

UTF-8 (8-bit Unicode Transformation Format) 是一种针对 Unicode 的可变长度字符编

码,它使用一到四个字节来表示字符,例如, ASCII 字符继续使用一个字节编码,阿拉伯文、希腊文 等使用两个字节编码,常用汉字使用三个字节编码,等等。

因此,我们说, UTF-8Unicode 的实现方式之一,其他实现方式还包括 UTF-16 (字符用两个或 四个字节表示)和 UTF-32 (字符用四个字节表示)。

4 Python中的字符类型


4.1 Python 中的字符类型

Python2 的默认编码是 ASCII,Python3 的默认编码是 utf-8

Python2 中有两种和字符串相关的类型: str 和 unicode ,它们的父类是 basestring 。其中,

str 类型的字符串有多种编码方式,默认是 ascii ,还有 gbk , utf-8 等, unicode 类型的字符

串使用 u’…’ 的形式来表示,下面的图展示了 str 和 unicode 之间的关系:

4.2 UnicodeEncodeError & UnicodeDecodeError 根源

用 Python2 编写程序的时候经常会遇到 UnicodeEncodeError 和 UnicodeDecodeError ,它

们出现的根源就是如果代码里面混合使用了 str 类型和 unicode 类型的字符串, Python 会默认 使用 ascii 编码尝试对 unicode 类型的字符串编码 (encode) ,或对 str 类型的字符串解码 (decode) ,这时就很可能出现上述错误。

下面有两个常见的场景,我们最好牢牢记住:在进行同时包含 str 类型和 unicode 类型的字符串操作时, Python2 一律都把 str 解码 (decode )成 unicode 再运算,这时就很容易出现 UnicodeDecodeError 。

让我们看看例子:

  1. s = ‘你好’ # str 类型, utf-8 编码

  1. u = u’世界’ # unicode 类型

  1. s + u # 会进行隐式转换,即 s.decode(‘ascii’) + u

  1. Traceback (most recent call last):
  1. File “”, line 1, in 6. UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe4 in position 0: ordinal not in range(128)

为了避免出错,我们就需要显示指定使用 ‘utf-8’ 进行解码,如下:

  1. s = ‘你好’ # str 类型,utf-8 编码

  1. u = u’世界’

  1. s.decode(‘utf-8’) + u # 显示指定 ‘utf-8’ 进行转换 5. u’\u4f60\u597d\u4e16\u754c’ # 注意这不是错误,这是 unicode 字符串

这个破问题也困扰了我一晚上,UnicodedecodeError编码问题解决方法汇总:

Python:UnicodedecodeError编码问题解决方法汇总-彻底解决

异常处理: UnicodeDecodeError: ‘utf-8’ codec can’t

Python 出现的UnicodeDecodeError的几种情况记录及解决办法

除此之外,还可能是导入程序的文件有问题,.csv等等。

5 小结


(1)UTF-8 是一种针对 Unicode 的可变长度字符编码,它是 Unicode 的实现方式之一。

(2)Unicode 字符集有多种编码标准,比如 UTF-8, UTF-7, UTF-16 。

在这里插入图片描述

感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:

① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值