目录
一、字符问题
字符串的概念就是一串字符,字符的概念?在英文中,我们可以认为每个数字、字母等都是字符,在中文中,每个汉字也都是字符,还有很多很多的符号也都是字符,但是这是现实世界中的字符,为了将现实世界中的字符存储到计算机上,我们就需要一套编码标准,比如最常见的unicode标准。
在unicode标准中,主要有两个概念最重要,一个是字符的标识(码位),一个是具体的字节表述(编码得到的二进制流)。
- 字符的标识即码位,也可以认为是索引,比如我们把现实世界中的所有字符排成一列,然后按按十进制从索引0开始往后标注,则这个索引就是码位。
- 字符的具体表述取决于所用的编码。编码的作用是把码位转换成字节序列,给计算机存储用的,把字节序列再转换成码位则是解码的过程。
- 一套字符的码位就是一个字符集,一般所说的编码即是对字符集中的码位进行编码。比如ascii字符集,其编码就是直接把码位转换成对应的8位二进制数。而对于unicode标准中的字符集来说,直接转换成二进制数需要占用太多存储空间,因此另寻了其它的编码方式,比如UTF-8。
综上,每个字符都对应字符集中的一个码位(可以看成是十进制索引,是字符的编码,可如果把字符类比为学校里的学生,则码位就是学生的学号),每个码位都可以通过特定的编码方式编码成字节序列。从码位(unicode)到字节序列(bytes)是编码,从字节序列到码位是解码。在python3中,str类型即相当于python2中的unicode类型,即内存中以码位对应二进制序列存储,而没有进行编码。
unicode标准将字符集与编码方式进行了解耦,而ascii和gbk等没有做解耦,因此谈起后者一般指的是字符集和编码都有,且ascii和gbk都是只有一种编码方式。unicode标准的字符集和编码方式都有多种。
如下例子:


str对象调用encode方法可以转换成bytes对象,bytes对象调用decode方法可以转换成str对象,其中用的转换方法都是utf8,bytes对象字面量都是以b开头的。
二、字节概要
bytes与bytearray类型
python内置了两种基本的二进制序列类型:不可变的bytes类型和可变的bytearray类型。
bytes或bytearray对象的各个元素是介于0-255之间的整数,但其切片是对应bytes或bytearray类型的二进制序列类型。如下例子:
cafe = bytes("cafe", encoding='utf_8')
print("bytes类型的cafe")
print(cafe)
print(cafe[0])
print(cafe[:1])
print(cafe.decode('utf_8'))
print('\n')
print("bytearray类型的cafe")
cafe_arr = bytearray(cafe)
print(cafe_arr)
print(cafe_arr[-1])
print(cafe_arr[-1:])

bytes对象是以特定编码的形式存储在内存中,如上例中的cafe,即以utf_8编码的形式构建的bytes对象。其中第一个元素cafe[0]是c,对应码位当然也就是99,因为各个字符集都是兼容ascii的,在ascii中a是97,c自然就是99。但是其只含有一个元素的切片得到的还是一个bytes对象b'c'。把bytes对象解码成unicode对象即可用print直接打印出来。bytearray对象没有字面量的说法,如图所示是以bytes对象字面量加上bytearray()的形式打印的。且其中的元素也是0-255的整数。
bytes和bytearray序列对象中各个元素都是0到255之间的整数,其实就是代表了一种8位的二进制表示。二进制序列对象中各个字节的值可能用三种不同的方式显示:

比如在例子 b'caf\xc3\xa9' 中,前三个字节的值b'caf'是在可打印的ascii范围内,第四个字节 ‘\xc3’和第五个字节 '\xa9' 则不在,即上边的第三种情况,其它字节的值,使用十六进制转义序列。
如下边例子,bytes等二进制序列类型相当于对码位进行编码,而unicode或str类型则相当于直接存储码位,下边两行都输出hello,这是因为不管是什么类型的编码,都是兼容ASCII的,而ASCII中编码就等于码位,因此下边两个的输出都是hello,但是一些不在ascii字符集中的字符,其bytes表示和str表示就不一样了。
b = b'hello'
print(b)
print(b.decode('utf_8'))
![]()
二进制序列类型bytes和bytearray有很多方法都是跟str通用的,也有一个其特有的方法fromhex,作用是解析十六进制数字对,来构建一个二进制序列类型。如下所示,通过一个十六进制序列构建出的二进制序列类型对象b解码成str后是1KΩ。
b = bytes.fromhex('31 4B CE A9')
print(b)
print(b.decode('utf_8'))
![]()
构建bytes或bytearray对象可以调用构造方法,传入如下参数:
- 一个str对象和一个encoding关键字参数
- 一个可迭代对象,提供0~255之间的数值
- 一个实现了缓冲协议的对象(如bytes、bytearray、memoryview、array.array),此时把源对象中的字节序列复制到新键的二进制序列对象中。
如下例子,使用数组对象来构造bytes对象。定义数组对象的时候必须要指定类型,跟C语言数组比较相似,这里‘h’说明数组元素是16位即2字节的整数,一共有5个元素,因此最后生成的bytes对象octets是一个有10个字节的二进制序列对象。

结构体和内存视图
struct模块提供一些函数,将打包的字节序列转换成不同类型字段组成的元组,或把元组转换成打包的字节序列。struct模块具体分析如下。

本文详细介绍了Python3中字符、字节的概念,包括Unicode编码、字节序列的处理、编解码问题及常见错误。讲解了str与bytes的相互转换,struct模块的应用,以及处理文本文件和字符串规范化的方法。同时,讨论了Unicode数据库和双模式API在正则表达式和os模块中的使用。
最低0.47元/天 解锁文章
1317

被折叠的 条评论
为什么被折叠?



