Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
新手必看:用CST做电磁场与电磁波仿真?先理清这些核心问题
对于电磁工程领域而言,CST(Computer Simulation Technology)是解决高频、高速电磁问题的关键工具,凭借精准的模拟能力,广泛应用于天线设计、射频器件开发、电磁兼容(EMC)分析等场景。不过,高效开展电磁场与电磁波仿真的前提,是先搞懂基础认知与关键前提问题;若前期准备不到位,不仅可能导致仿真结果出现偏差,还会严重影响整体工作效率。
思茂信息
2025/09/29
1570
新手必看:用CST做电磁场与电磁波仿真?先理清这些核心问题
不懂电磁仿真技术原理?CST 电磁仿真软件帮你搞清楚
随着现代科技的迅猛迭代,电磁技术已深度融入社会生产生活的方方面面:小到我们日常依赖的手机、电脑,大到航空航天、通信传输、医疗设备等高端领域,电磁现象始终贯穿其中,成为推动技术发展的关键隐形力量。而电磁仿真技术,作为探索电磁规律、优化电磁系统性能的核心手段,其重要性日益凸显。在众多电磁仿真工具中,CST 电磁仿真软件凭借卓越性能脱颖而出,为工程师与科研人员搭建了强大的技术平台,助力他们高效破解各类复杂电磁难题。
思茂信息
2025/09/25
1440
不懂电磁仿真技术原理?CST 电磁仿真软件帮你搞清楚
剥开天线的外衣,与天线坦诚相见!
基站的天线,比基站本身更为醒目。“天线”这两个字,也不像它们看上去那样简单。但是,我们会尽力把它说得简单有趣。
通往ICT之路
2025/01/07
2630
剥开天线的外衣,与天线坦诚相见!
NFC天线工作原理、设计
继公众号之前推送过的《NFC芯片选型及基本电路框架》之后,本篇文字聊聊NFC天线工作原理及其设计,由于篇幅有限,该内容分两篇文字进行阐述
硬件大熊
2022/06/23
5.3K0
NFC天线工作原理、设计
天线是如何发射电磁波的
总结起来,天线发射电磁波的关键在于利用交变电流在其结构上产生的周期性变化的电磁场,当这些场离开天线进入自由空间后,它们便形成了向外传播的电磁波,携带信息穿越空间直至被远方的接收天线捕获并还原为电信号。
用户11339509
2024/12/09
2690
射频通信, 电磁波等无线基础知识科普!
电磁波是能量的一种,凡是高于绝对零度的物体,都会释出电磁波。电与磁可说是一体两面,电流会产生磁场,变动的磁场则会产生电流。变化的电场和变化的磁场构成了一个不可分离的统一的场。
通往ICT之路
2024/04/09
2790
射频通信, 电磁波等无线基础知识科普!
一个小灯泡引发大论战:千万粉丝科普up主翻车,伊朗“唐马儒”、李永乐等下场,30万公里导线引百万网友围观
假设存在一个巨型电路,其中一个电源、一个开关、一个理想灯泡(一有电流就能亮的那种),通过2根30万公里长的导线连接,灯泡和开关之间仅相隔1m的距离,就像这样:
量子位
2022/01/14
4210
一个小灯泡引发大论战:千万粉丝科普up主翻车,伊朗“唐马儒”、李永乐等下场,30万公里导线引百万网友围观
离天线越近,信号质量真的越好吗?
在日常生活中,我们或许会直观地认为,距离天线越近,接收到的信号质量应当越高。然而,这一直觉在电磁波传播领域,尤其是在无线通信的范畴内,并不总是成立。
通往ICT之路
2024/06/07
3980
离天线越近,信号质量真的越好吗?
什么是天线阵列?
偶极子(dipole):当两个对称的导线张开、距离增大,整个导体尺寸等于波长的一半时,该导体上感应到的无线电刚好处于谐振状态,此时电磁波的辐射效率最高。这个导体叫半波振子,也叫偶极子(Dipole),如图1所示。
通往ICT之路
2025/02/28
8001
什么是天线阵列?
黑科技 | 新型ME天线仅为小型天线的百分之一,可广泛用于智能硬件中
新型微小型天线未来可用于无线通信、物联网、可穿戴设备、智能手机等。 近日,《自然通讯》杂志发布了一篇文章,它描述了一种新型天线设计方案,文中表示,根据此方案将能制造出比当前小型天线还要小一百倍的天线。 图 | 目前的小型天线产品 目前,现有的小型天线都是基于电磁共振,因此天线的尺寸需要根据电磁波的波长。现实应用的天线长度至少都要大于波长的十分之一,近十年来,天线的进一步小型化已经是一个公开的难题。 而设计的新型ME天线(尺寸小于波长的千分之一)在最先进的小型天线上实现了1-2个数量级的缩小,而且性能也没有下
镁客网
2018/05/30
1.4K0
看完马达原理动图,你可能更快成为一名合格的攻城狮
要问想成为攻城狮的朋友们,哪门功课最难学,电机恐怕是排名靠前的几个选项之一,究其原因,很多人认为是太抽象了。所以,今天小便就搜集了一大堆各种电机原理动图,看完之后,你可能更快成为一名合格的攻城狮。 电机(俗称“马达”)是指依据电磁感应定律实现电能转换或传递的一种电磁装置。它的主要作用是产生驱动转矩,作为用电器或各种机械的动力源。 发电机的主要作用是利用电能转化为机械能。 电动机主要包括一个用以产生磁场的电磁铁绕组或分布的定子绕组和一个旋转电枢或转子和其它附件组成。在定子绕组旋转磁场的作用下,其在电
机器人网
2018/04/12
1.4K0
看完马达原理动图,你可能更快成为一名合格的攻城狮
共模干扰和差模干扰,看完终于明白了
共模干扰在导线与地(机壳)之间传输,属于非对称性干扰,它定义为任何载流导体与参考地之间的不希望存在的电位差。
AI 电堂
2022/12/08
3.4K0
共模干扰和差模干扰,看完终于明白了
无线充电技术简介
无线充电技术最早出现于19世纪末,当时的物理学家Nikola Tesla演示了磁共振耦合——在两个电路(一个发射器一个接收器)之间建立磁场,通过空气来传输电能。但在之后的大约100年时间里,这项技术并没有得到多少实际应用。直到近年来智能终端设备的广泛应用,尤其是智能手机的普及,才让无线充电技术得以重新发展和推广。
233333
2021/06/10
3.2K0
无线充电技术简介
电磁场与电磁波实验 01 – | 位移电流测量及电磁场与电磁波的存在实验[通俗易懂]
随时间变化的电场要在空间产生磁场,同样,随时间变化的磁场也要在空间产生电场。电场和磁场构成了统一的电磁场的两个不可分割的部分。能够辐射电磁波的装置称为天线,用功率信号发生器作为发射源,通过发射天线产生电磁波。如果将另一副天线置于电磁波中,就能在天线体上感生高频电流,我们可以称之为接收天线,接收天线离发射天线越近,电磁波功率越强,感应电动势越大。如果用小功率的白炽灯泡接入天线馈电点,能量足够时就可使白炽灯发光。接收天线和白炽灯构成一个完整的电磁感应装置。 当越靠近发射天线,灯泡被点的越亮。越远离天线,灯泡越暗。
全栈程序员站长
2022/11/17
2K0
电磁场与电磁波实验 01 – | 位移电流测量及电磁场与电磁波的存在实验[通俗易懂]
EMC电磁屏蔽:静电、磁场与天线耦合
不管什么电子产品,EMC始终是其需要面对的问题,EMC全拼是Electromagnetic Compatibility即电磁兼容性,EMC分为EMS(electromagnetic susceptibility)电磁抗扰度和EMI( Electromagnetic interference)电磁干扰两部分,一个是评估产品自身稳定性的,另一个是评估产品对外噪声水平的,都是产品质量的重要指标,本文以手机为例,介绍EMC、静电浪涌的基本原理以及常见解决措施,有助于指导工程师PCB layout以及解决实际EMC问题。
工程师看海
2022/11/29
1K0
EMC电磁屏蔽:静电、磁场与天线耦合
接收天线有什么不一样?
天线可以将无线电设备产生的高频电流信号转换成电磁波并发送到空中,同时也负责捕捉空中的电磁波并将其转换回高频电流信号。
通往ICT之路
2024/05/17
4480
接收天线有什么不一样?
电磁兼容(EMC)的标准与测试内容
在国际范围上,电磁兼容标准的制定已经有了70多年的发展历程,最早为了保护无线电通信和广播,国际无线电干扰特别委员会(CISPR)对各种用电设备和系统提出了相关的电磁干扰发射限值和测量方法。到了20世纪60~70年代,由于电子、电气设备的小型化、数字化和低功耗化,人们开始考虑设备的抗干扰能力,世界各大标准化组织和各国政府机构也相继制定了许许多多的电磁兼容标准。咱们今天就和海翎光电的小编一起来聊聊电磁兼容的基础知识和测试内容。
利又德智能感知
2023/02/03
3.4K0
电磁兼容(EMC)的标准与测试内容
基站信号辐射,到底会不会影响健康?
现如今,移动通信技术渗透到了社会生活的方方面面。各式各样的手机应用,已经彻底改变了我们的生活。
鲜枣课堂
2020/10/09
6000
基站信号辐射,到底会不会影响健康?
一文读懂电与电路
在我们的日常生活和工作中,几乎都要用到电,如LED节能灯的发光、洗衣机洗衣服和空调的制冷制热,都是电作用的结果。那么,电究竟是什么呢?
华东子
2024/11/07
3550
一文读懂电与电路
【深度科普】辐射的真相
1. 电离辐射是一种可以把物质电离的辐射,电离辐射对生物是危险的。不是所有的辐射都是电离辐射。
鲜枣课堂
2019/07/22
6760
【深度科普】辐射的真相
推荐阅读
相关推荐
新手必看:用CST做电磁场与电磁波仿真?先理清这些核心问题
更多 >
交个朋友
加入架构与运维工作实战群
高并发系统设计 运维自动化实践
加入架构与运维趋势交流群
技术趋势前瞻 架构演进方向
加入[架构及运维] 腾讯云技术交流站
云架构设计 云运维最佳实践
换一批
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验