给小白写的 “搞懂 Python 中的编码”

栏目: Python · 发布时间: 5年前

内容简介:1. 原理:

很多初学者会被 Python 中UnicodeDecodeError弄得一头污水,相信你也一定遇到过这个问题,这里我们讲一下编码相关的知识。 (部分内容参考了 《编写高质量Python代码的59个有效方法》一书

1. 原理:

    计算机中所有的内容都是用1和0组成的(二进制)。 这和计算机的硬件实现原理相关,通常组成计算机的逻辑电路只有接通和断开两个状态,分别用来表示1和0。这样一个逻辑电路组成的位置叫一个比特(bit),一个位置能表示的内容有限,但组合起来,多个一起用就能发挥出无限威力,我们把8位放到一起组成一个 字节(Byte) 。可以得知,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),字节对应的二进制数字被用来表示大小写英文字母、数字和一些符号,比如65代表大写字母A,122代表小写字母z,这个对应关系就是 ASCII编码表, ASCII是American Standard Code for Information Interchange的简称,是为美国英语而设计的。

ASCII 码使用指定的 7 位 或 8 位二进制数组合来表示 128 或 256 种字符。 标准ASCII 码也叫基础ASCII码,使用 7 位二进制数(最开始的那1位固定为0) 简称 7位ASCII 来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。

有了这个编码表,在计算机中处理大小英文,数字,标点基本上够用了,但问题是我们的中文有非常多汉字,总数超过了8万,常用的都有3500个之多,更何况世界上还有各种其它语言,那么在计算机中怎么表示数量这么庞大的字符呢?

解决这个问题很简单,每个字符用多个字节来表示,一个不够用两个,两个不够用三个,使用足够多的字节肯定是能表示出来的。使用这种“原始”的多个字节值表示其它的复杂字符,这些8位称为 原始8位值。

但问题又来了,各平台,各国家规定都不统一,同样的编码,在一个国家表示某个文字,在另一个国家可能被用来表示另一个文字,在信息交流的时候经常会出现“乱码”。为了解决这个问题,必须得有统一的标准,于是Unicode(统一码、万国码、单一码)就诞生了。Unicode 也称为 UCS(Universal Coded Character Set: 国际编码字符集合) 是一个字符集合。UNICODE标准也在不断发展完善,目前使用 4个字节 表示一个字符可以表示出全世界所有字符。那UNICODE在计算机中如何存储呢,存储时也必须占用4个字节么,这就要涉及到编码的知识。

    UNICODE最常见的编码方式是UTF-8 ,另外还有UTF-16,UTF-32等。如果每个字符都用四个字节来存储,纯英文内容占用空间变成了原来ASCII的四倍,非常浪费空间。而UTF-8编码比较巧妙,采用的是变长的方法,也就是一个字符在UTF-8编码表示时占用1个字节到4个字节不等,兼容ASCII,表示纯英文时,并不会占用更多长度。

2. 转换过程

UTF-8,GBK等,通过 解码(decode) 得到UNICODE,UNICODE通过 编码(encode) 可以转换成GBK或UTF8等编码( 原始8位值 ),转换如下图所示。

给小白写的 “搞懂 Python 中的编码”

3. 示例:

u'6啊'.encode('utf8')  ->  b'6\xe5\x95\x8a'(16进制表示的 原始8位值

u'6啊'.encode('gbk')  ->  b'6\xb0\xa1'       (16进制表示的 原始8位值

从上面的例子可以看到6是用一个字节表示的,汉字“啊”在utf8中是用三个字节表示的(gbk中是两个字节),其中\xe5意思就是16进制的e5,代表一个8位二进制:

bin(int('e5', base=16)) -> '0b11100101'。

再比如 “涂 这个汉字,unicode 为 u'\u6d82'

使用utf8编码时 '\xe6\xb6\x82'  11100110  10110110  10000010  三个8位

使用gbk编码时 '\xcd\xbf'          11001101  10111111  两个8位

4. 结论:

4.1 Unicode可以通过不同的字符编码来实现,最常用的是utf8,它是ASCII码的超集。

4.2 Python 3 有两种表示字符序列的类型:bytes 和 str。bytes 的实例包含原始的8位值,str 的实例包含unicode字符。

4.3 Python 2 也有两种表示字符序列的类型 ,分别叫做 str 和 unicode。与Python3不同的是,Python2中 str 实例包含原始的8位值;而unicode的实例,则包含unicode字符。Python2里面 不够严格 ,如果str只包含7位ASCII字符,那么unicode和str实例似乎就成了同一种类型: a) 可以相加 b) 可以比较 c) 可以用 %s 格式化。如果使用的时候不注意在特定的场景下就会带来问题。

4.4 在编程时,编码和解码尽量在最外围做 ,程序处理逻辑中尽量全部使用unicode,当有必要时( 比如写入到文件 )才 encode 转换成utf8等编码

从文件等中读取后尽快decode转换成unicode。这样可以大大减少编码带来的问题。

5. 读者思考:

1. utf8为什么这么成功,它是如何兼容ASCII的?

2. 通过上面的示例,是不是发现用gbk存储中文比utf8更省空间,那为什么一般情况下不用gbk来储存,而是用utf8呢?

给小白写的 “搞懂 Python 中的编码”


以上所述就是小编给大家介绍的《给小白写的 “搞懂 Python 中的编码”》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

知识发现

知识发现

史忠植 / 2011-1 / 59.00元

《知识发现(第2版)》全面而又系统地介绍了知识发现的方法和技术,反映了当前知识发现研究的最新成果和进展。全书共分15章。第1章是绪论,概述知识发现的重要概念和发展过程。下面三章重点讨论分类问题,包括决策树、支持向量机和迁移学习。第5章阐述聚类分析。第6章是关联规则。第7章讨论粗糙集和粒度计算。第8章介绍神经网络,书中着重介绍几种实用的算法。第9章探讨贝叶斯网络。第10章讨论隐马尔可夫模型。第11章......一起来看看 《知识发现》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码