python中的字符与编码

相信不仅仅是python学习者,所有需要处理字符与二进制流数据的同学都遇到过字符与编码的问题,下面我会给出我的理解。

1、首先什么是字符,什么是编码

我的理解是字符是语言层面的,不如a,b,c这些是英文字符,“中”,“本”,“聪”这种是中文字符,这些都是人脑中处理的语言的基本元素。那什么是编码呢,编码就是计算机处理的基本元素,也就是比特0和1,编码就是将字符转化成不同的比特流。

好了,问题来了,每个字符应该编码成多长的比特流?是不是每个字符需要用同样长度的比特表示?能不能用变长码表示?

答案是这取决于字符集的多少

比如,ASCII中只有英文字符和一些标点符号以及空格键等特殊符号,只需要8位比特就足够表示了(2^8=256个字符)

然而,这遇到其他语言的字符就不行了,比如中文,中文这种象形文字何止256个?所以8位已经不够了,需要用更多的位数的比特来表示,也就是常见的GBK编码。

那有没有一种同意的编码能囊括所有语言的字符呢?有,那就是unicode.

在unicode中,所有的字符都用两个字节来表示。

那有没有变长码呢?有,比如utf-8

所谓变长码就是不同的字符用不同长度的比特流表示。

2、python中的字符与编码

依旧用解答问题的方式来阐述

1)python中用的是什么编码?

我们知道,python首先需要从*.py文件中将字符读入,那么python该用什么样的编码方式读入该文件呢?答案是文件的存储的编码方式就是python读入内存中的时候的编码方式,比如用的是utf-8(利于存储),那么就按utf-8的编码方式读入。读入之后 呢?如何表示?这在python2.*与python3.*中是不一样的。python2中的字符串的数据类型是str(byte类型),也就是说是什么编码方式读入的就怎样在内存中表示,如下图

 

a的编码方式是用三个字节来表示,str类型本质上是一个byte类型,它不关注你的编码是什么,它只会保存你编码之后的字节流,因此a的长度是3,表示该string是三个字节长的数据。再看下图

内建函数unicode将a变成Unicode对象,utf-8指定的是a的编码方式,可以看到转化之后,b的长度为1,因为Unicode编码中,所有的字符都是用两个字节表示的。

同时,unicode类中的encode函数会按照你需要的编码方式编码,如上图的b.encode("utf-8"),就是将b编码成utf-8表示的字符串(str类型)

总结:再python2中,所有的字符串都是用str来表示,str不是编码方式,而是按照文件的(或者在terminal中设置的)编码方式,存储编码之后的字节流。而Unicode对象是将字符编码成Unicode之后的数据类型Unicode对象存储的一定是Unicode编码

而在python3中,内存中统一用Unicode对象表示字符,也就是按照py文件中的编码方式读入之后,统一转化为Unicode对象。就避免了繁琐的编码问题,但是也有缺点,就是如果程序需要处理每一个字节的话,就需要做另外的转化工作才能获取到字节了。

2)为什么python的字符与编码看起来如此复杂?

第一个是因为部分人可能会混淆字符集和编码方式的概念,认为字符和编码是同一回事。

第二是混淆数据类型与编码方式的概念,认为数据类型和编码方式同一回事,所谓程序中的数据类型,指的是数据如何存储,比如str类型就是按照字节为最小单位进行数据的存储,而编码方式是指字符是用多少字节来表示,具体表示为什么

总结:对应容易出错的,容易混淆的概念,首先要清楚了解每个概念的意思,然后再回头看再编程语言中的用法,通常需要从计算机底层,高级语言(逻辑)层面等去理解。越是层次分明,概念越是清晰,就越容易理解

---------------------------------------------------------------------------------------------------------------------------------

转载请注明出处https://blog.csdn.net/ganzr/article/details/85780319

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值