首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >python字符编码

python字符编码

作者头像
py3study
发布于 2020-01-13 04:47:09
发布于 2020-01-13 04:47:09
1.8K00
代码可运行
举报
文章被收录于专栏:python3python3
运行总次数:0
代码可运行

近期接触到python的编码相关的东西,发现自己了解的不是太系统,故通过搜索资料做了一些总结。

字符编码

字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。

我们知道,计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。ASCII码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。

亚洲国家的文字,使用的符号就很多了,汉字就多达10万左右。一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256x256=65536个符号。可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。Unicode是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字严。具体的符号对应表,可以查询unicode.org。目前,现代操作系统和大多数编程语言都直接支持Unicode。

现在,捋一捋ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
字母A:ASCII编码是十进制的65,二进制的01000001;
字符0:ASCII编码是十进制的48,二进制的00110000,注意字符'0'和整数0是不同的;
汉字中: 已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101

你可以猜测,如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001。

这里就有两个严重的问题,第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1)出现了 Unicode 的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示 Unicode。
2)Unicode 在很长一段时间内无法推广,直到互联网的出现。

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8 是 Unicode 的实现方式之一。

UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。UTF-8 的编码规则很简单,只有二条:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

下表总结了编码规则,字母x表示可用编码的位。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Unicode符号范围     |        UTF-8编码方式
(十六进制)        |              (二进制)
----------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

下面,还是以汉字为例,演示如何实现 UTF-8 编码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
严的 Unicode 是4E25100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此严的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从严的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,严的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5

python默认编码

源代码文件读取默认编码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
python2.x中,脚本源代码文件读写的时候是默认使用ASCII来处理,由于ASCII不支持中文,故会报错。故当我们的脚本源代码中出现中文的时候,我们一般增加# -*- coding: utf-8 -*-来解决问题,标识用utf-8编码来读取文件。

python3.x中,脚本源代码文件读写的时候是默认使用UTF-8来处理,对中文比较友好。

解释器执行时对str类型使用的默认编码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
python2.x: 
python中字符串的类型都属于str类型,而当python2.x的解释器内部执行的时候str默认也是使用ASCII编码,可以通过sys.setdefaultencoding('utf-8')来改变默认编码:

>>> '离离原上草,一岁一枯荣'.encode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)
>>> sys.getdefaultencoding()
'ascii'
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf-8')
>>> '离离原上草,一岁一枯荣'.encode('utf-8')
'\xe7\xa6\xbb\xe7\xa6\xbb\xe5\x8e\x9f\xe4\xb8\x8a\xe8\x8d\x89\xef\xbc\x8c\xe4\xb8\x80\xe5\xb2\x81\xe4\xb8\x80\xe6\x9e\xaf\xe8\x8d\xa3'

python3.x: 
在python3.x中,str类型的编码类型为utf-8编码:
In [16]: sys.getdefaultencoding()
Out[16]: 'utf-8'
In [17]: '离离原上草,一岁一枯荣'.encode('utf-8')
Out[17]: b'\xe7\xa6\xbb\xe7\xa6\xbb\xe5\x8e\x9f\xe4\xb8\x8a\xe8\x8d\x89\xef\xbc\x8c\xe4\xb8\x80\xe5\xb2\x81\xe4\xb8\x80\xe6\x9e\xaf\xe8\x8d\xa3'

我们发现如上python3的out[17]前面有一个b,标识输出是一个bytes类型。这是因为:Python3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python3的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。

Python3对bytes类型的数据用带b前缀的单引号或双引号表示: x = b'ABC' 要注意区分'ABC'和b'ABC',前者是str,后者虽然内容显示得和前者一样,但bytes的每个字符都只占用一个字节。

以Unicode表示的str通过encode()方法可以编码为指定的bytes,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。在bytes中,无法显示为ASCII字符的字节,用\x##显示。

反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

如果bytes中包含无法解码的字节,decode()方法会报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
  ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'

要计算str包含多少个字符,可以用len()函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> len('ABC')
3
>>> len('中文')
2

len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6

可见,1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。

参考

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431664106267f12e9bef7ee14cf6a8776a479bdec9b9000

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/08/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python_实用入门篇_05
在计算机硬件中,编码(coding)是指用代码来表示各组数据资料,使其成为可利用计算机进行处理和分析的信息。代码是用来表示事物的记号,它可以用数字、字母、特殊的符号或它们之间的组合来表示。
py3study
2020/01/19
5510
Python_实用入门篇_05
Python3的编码问题
​介绍Python3中的编码问题前,第一个段落对字节、ASCII​与Unicode与UTF-8等进行基本介绍,如果不对这几种编码犯头晕,可直接跳过。
py3study
2020/01/10
1.3K0
Python3的编码问题
[CS]聊聊字符编码
用爬虫在百度爬图片的时候,发现部分查询关键字的时候,出现爬不出图片的情况.比如在爬鱼的时候,就没有结果.爬鱼 图片就会有结果.
wOw
2018/09/18
1.3K0
字符、字符集、编码,以及它们python中会遇到的一些问题(下)
在看了很多的博客文章之后,总结整理得到了以下文章,非常感谢这些无私奉献的博主! 文章末尾有本文引用的文章的链接,如果有漏掉的文章引用,可以发邮件联系我,随后再次附上链接! 侵删!!! 这一部分是下篇,主要讲的是编码部分,以及在python中会遇到的一些编码问题,偏向于实际应用一点。 上篇介绍了字符、字符集的一些概念,以及他们在python中的一些简单的代码示例,偏向于概念。 上篇地址:http://www.cnblogs.com/echo-coding/p/7435118.html 这绝对是个源
Echo_fy
2018/06/20
2.1K0
python-字符编码
注·比如,简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示 256 x 256 = 65536 个符号,所以两个字节其实也不够表示出所有的中文,遇到生僻字可能需要更多位来表示。
HammerZe
2022/03/25
8650
python-字符编码
AI 学习之路——轻松初探 Python 篇(三)
这是「AI 学习之路」的第 3 篇,「Python 学习」的第 2 篇 Python 字符串使用和 C 语言比较类似,但还有一些我们值得注意的地方需要关注,用这篇文章来帮助大家掌握 Python 的字符串吧! 编码 不论什么语言,我们都需要考虑一下这个语言的编码问题。「ASCII」编码是我们最熟悉的编码,但它只有 127 个字符被编码到计算机里面了,显然,像中日韩这类国家,语言文字比较特殊,就需要自己来指定编码格式。 比如,中国自己就制定了「GB2312」编码,韩文则是「EUC_KR」,俄语是「KOI8
小之丶
2018/03/07
8300
AI 学习之路——轻松初探 Python 篇(三)
Python学习总结4--字符串和编码
一、编码历史     由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。     但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。     Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了     本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码
曼路
2018/10/18
4740
Python学习总结4--字符串和编码
教你一招 | Python3新特性(一) :字符串
从python2转到python3的第一个问题就是字符串的问题,我花了些时间把我能想到的和字符串处理有关的东西都整理如下。 1、Python2的字符串编码 在python2.X中的字符串编码有点麻烦,它所有的“普通字符串”是ascii码存储的,unicode字符串是16位unicode码存储的,这个时候就经常出现转换、乱码的问题。 1.1 python2中的普通字符串 >>> a="abc" >>> print a abc >>> print repr(a) 'abc' >>> type(a) <type
CDA数据分析师
2018/02/05
7040
编码漫谈
Unicode用数字0-0x10FFFF来映射字符,最多可以容纳1114112个字符,或者说有1114112个码位,理论上是足够用的。
老高的技术博客
2022/12/27
3550
编码漫谈
【python系统学习16】编码基础知识
就是把人类认识的中英文字、其他国家语言、数字甚至运算符等符号转成二进制的0、1,并进行存储和传输。
xing.org1^
2020/05/31
7350
基础知识:字符编码
1、什么实字符编码:将人识别的字符转换成计算机能识别的01,而转换的过程或者规则就是字符编码表。
py3study
2020/01/17
5870
Python基础教程之字符串和编码
1. 字符编码 由于计算机只能处理数字,如果要处理文本就必须将文本转换为数字才能处理,最早设计的时候采用8b 表示一个字节,一个字节能够表示的最大整数是255,如果要表示更大的整数,就必须用多个字节。另外由于计算机是美国人发明的,所以计算机早期只有127个字符被编码到计算机了,也就是Ascii码,后来要处理中文中国就指定了GB2312 ,但是其他国家也有自己的语言 然后就有了不同的标准, 所以就有组织将所有的统一成 Unicode编码。 2. python字符串 在python 中字符串支持多语言,py
执行上下文
2022/07/26
3100
Python 编码与解码
  字符串类型是对人类友好的符号,但计算机只认识一种符号,那就是二进制(binary)数,或者说是数字。   为了用计算机可以理解的数字描述人类使用的字符,我们需要一张数字与字符对应的表。我们都知道在计算机中 1 byte = 8bits,可以存储 0~255共256个值,也就是说 1byte最多可以表示 256 个字符,在最初的计算机世界中,256 足以容纳所有大小写英文字和阿拉伯数字 0~9以及一些常用的符号,于是就有了 ASCII 编码:
全栈测试开发日记
2023/02/02
1.2K0
Python 编码与解码
一篇文章理清python的字符编码
最近在用python接受网络数据的时候,输出时总是遇到编码的问题,虽然都解决了,但深刻意识到自己其实对python的编码并没有清晰的认识,所以才会遇到这样的问题。今天就此总结一下,以免日后夜长梦多。
梦飞
2022/06/23
8980
一篇文章理清python的字符编码
python--一文搞懂字符串的编解码
我们在使用python处理中文字符串时总会遇到一些问题,特别是一些老项目需要用到python2,中文显示乱码,文件读写异常等问题时常发生。
languageX
2023/05/04
1.8K0
【Python】3“字符串和编码“
小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点,并用字符串格式化显示出’xx.x%’,只保留小数点后1位: # !/usr/bin/env python3 # -*- coding: utf-8 -*- s1 = 72 s2 = 85 r = (85 - 72) / 72 * 100 print('%0.1f%%' % r)
肓己
2021/08/12
4850
Python学习笔记(一)——Python基础
本文是廖雪峰的Python教程的笔记,主要是摘抄一些重点。所以我把他划分到转载里。侵删。
蛮三刀酱
2019/09/10
5860
Python学习笔记(一)——Python基础
Python基础——PyCharm版本——第二章、数据类型和变量(超详细)
用print()在括号中加上字符串,就可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下:
红目香薰
2022/11/29
6540
Python基础——PyCharm版本——第二章、数据类型和变量(超详细)
浅析Python3中的bytes和str
Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python 3不会以任意隐式的方式混用str和bytes,你不能拼接字符串和字节流,也无法在字节流里搜索字符串(反之亦然),也不能将字符串传入参数为字节流的函数(反之亦然)。
py3study
2020/01/03
2.7K0
python中的编码与解码
编码/解码本质上是一种映射(对应关系),比如‘a’用ascii编码则是65,计算机中存储的就是00110101,但是显示的时候不能显示00110101,还是要显示'a',但计算机怎么知道00110101是'a'呢,这就需要解码,当选择用ascii解码时,当计算机读到00110101时就到对应的ascii表里一查发现是'a',就显示为'a'
李拜六不开鑫
2018/09/04
1.6K0
python中的编码与解码
相关推荐
Python_实用入门篇_05
更多 >
交个朋友
加入架构与运维工作实战群
高并发系统设计 运维自动化实践
加入架构与运维趋势交流群
技术趋势前瞻 架构演进方向
加入[架构及运维] 腾讯云技术交流站
云架构设计 云运维最佳实践
换一批
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验