1. Bytes, 回顾C/C++
在Python 3 中,bytes单独作为一个类型,不再和str类型混在一起。关于字符串和字节,我想先回顾下C/C++
在C/C++中,字符串是由char数组构成,每个元素是一个Char数据结构,数组的结尾是'\0'空字符。
- char是默认的unsigned的整型数据, 用于存储英文字符和小的整数(取值是0-255)。
- ASCII是char的子集,因此char很好存储英文字母, 满足存储英文字符的需求。
在C/C++中,int是整型的数据结构。而Python的int被设计成类,它有自己的属性和方法。这是Python和C/C++截然不同的地方。
同样在C/C++中的char整型,到了Python中,相应的是bytes类。我们可以这样说:Python中的Bytes类,本质上是C/C++中的char数组。
参考下面的代码:
my_bytes = b'Python'
print(type(my_bytes))
print(my_bytes[0])
print(my_bytes[0] + 1)
my_string = 'Python'
print(type(my_string))
print(my_string[0])
print(my_string[0] + 'y')
结果:
<class 'bytes'>
80
81
<class 'str'>
P
Py
结论:
在Python中,bytes和string都是序列类型,它们允许分片操作。但是bytes中的+号是加法运算符,而string中+号是连接符。
从这个意义上,Python仍然保持着与C的一致性。在C中,bytes是char数组,string是以空字符结尾的char数组。+号对于前者是运算,对于后者是连接。
2. Bytes类
a_num = b'\xff'
print(type(a_num[0]))
print(a_num[0])
结果:
<class 'int'>
255
结论:bytes类是序列,其中每个元素都是int类。但是它的取值范围被限定在:0-255。因为每个元素都是一个8bit的无符号整型,是一个字节,是一个char。
3. 字节与字符串的互转
当一个字符串被存储到计算机之中,它必然要按照某种格式(编码)去存储。因此字符串有encode方法,成了字节之后,有decode的方法。 计算机存储信息,以字节的方法存储,这些字节是没有任何意义的,当前仅当它们按特定的方法解码出来。
demo1:
中文的“你好”被编码储存,再解码被还原成“你好”
name = '你好'
nameBytes = name.encode('utf-8') # 字节
nameStr = nameBytes.decode('utf-8') # 字符串
print(name)
print(nameBytes[0], nameBytes[1], nameBytes[2])
print(nameStr)
结果:
你好
228 189 160
你好
demo2:
中文的“你好”被编码(utf-8)储存,再解码(utf-16)被还原成了韩语“뷤붥”
name = '你好'
nameBytes = name.encode('utf-8') # 字节
nameStr = nameBytes.decode('utf-16') # 字符串
print(name)
print(nameBytes[0], nameBytes[1], nameBytes[2])
print(nameStr)
结果:
你好
228 189 160
뷤붥
相信你已经了理解字符的编码和字节的解码了。