06-02字符串与bytes
字符串与bytes
python2和python3最大的区别
区别之处
str是文本序列
bytes是字节序列
文本是有编码的(utf-8, gbk, GB18030等)
字节没有编码的这种说法。
文本的编码指的是字符如何使用字节表示。
bytes与str关系
- python3字符串默认使用utf-8编码
- str转bytes:s.encode()
- 默认使用utf-8
- s.encode(‘GBK‘)# 指定传递不同的编码
- bytes转str:b.decode()
- bytes转二进制:bin(0xe9),str不能直接转二进制
- 跨网络交互,如果双方没有使用协定的编码处理,那么就会产生乱码。python3中统一发送bytes, 然后通过某种方式协商编码。
- 在Python2中,要么遇不到,要么遇到了无法解决, 所以在Python3中很好的解决了这个问题。
- string的所有操作bytes都支持
In [46]: s = ‘马哥教育‘ In [47]: type(s) Out[47]: str In [48]: s.encode() # 把字符串编码为bytes Out[48]: b‘\xe9\xa9\xac\xe5\x93\xa5\xe6\x95\x99\xe8\x82\xb2‘ In [49]: ‘马‘.encode() # 将‘马‘抓换为bytes Out[49]: b‘\xe9\xa9\xac‘ In [50]: ‘哥‘.encode() # 将‘哥‘转换为bytes Out[50]: b‘\xe5\x93\xa5‘ In [54]: 0xe9 # 16进制,encode一般是去掉0 Out[54]: 233 In [55]: 0xa9 Out[55]: 169 In [56]: 0xac Out[56]: 172 In [57]: bin(0xe9) # 转换为二进制 Out[57]: ‘0b11101001‘ In [58]: bin(0xa9) Out[58]: ‘0b10101001‘ # 0b代表的是二进制 In [59]: bin(0xac) Out[59]: ‘0b10101100‘ In [60]: 11101001 10101001 10101100 # 马字在计算机中的表示 In [61]: s.encode(‘GBK‘) # 指定传递不同的编码 Out[61]: b‘\xc2\xed\xb8\xe7\xbd\xcc\xd3\xfd‘ In [62]: s.encode() # 默认使用utf-8 Out[62]: b‘\xe9\xa9\xac\xe5\x93\xa5\xe6\x95\x99\xe8\x82\xb2‘ In [64]: b = s.encode() # 将utf-8转换为bytes存储 In [65]: b Out[65]: b‘\xe9\xa9\xac\xe5\x93\xa5\xe6\x95\x99\xe8\x82\xb2‘ In [66]: b.decode() # 把bytes转换为str Out[66]: ‘马哥教育‘ In [67]: type(b) Out[67]: bytes In [68]: b.decode(‘GBK‘) # utf-8无法转换为GBK --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) <ipython-input-68-041bea7b9d7a> in <module>() ----> 1 b.decode(‘GBK‘) UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xac in position 2: illegal multibyte sequence 跨网络交互, 如果双方没有使用协定的编码处理,那么就会产生乱码。 python3中统一发送bytes, 然后通过某种方式协商编码。 在Python2中,要么遇不到,要么遇到了无法解决, 所以在Python3中很好的解决了这个问题。 string的所有操作bytes都支持
bytes的创建
- bytes由str通过encode方法转换得到
- 通过b前缀直接定义bytes
In [4]: b = b‘abc‘ In [5]: type(b) Out[5]: bytes In [6]: b.decode() Out[6]: ‘abc‘
bytes操作
除了encode外, str操作, 都有对应bytes的版本, 但是传入参数必须是bytes。
bytes操作是按照字节来的
In [7]: b.‘abc‘.find(‘b‘) # 参数必须也是bytes File "<ipython-input-7-f89f1c2c6bad>", line 1 b.‘abc‘.find(‘b‘) ^ SyntaxError: invalid syntax In [8]: b‘abc‘.find(b‘b‘) # 参数必须是bytes Out[8]: 1 In [10]: ‘马哥教育‘.encode().find(b‘\xa9‘) # bytes操作是按照字节来的 Out[10]: 1 In [11]: len(‘马哥教育‘.encode()) # 按照字节来的 Out[11]: 12 In [13]: b.decode() # 转换为str Out[13]: ‘abc‘ In [14]: b.hex Out[14]: <function bytes.hex> In [15]: b.hex() # 转换为16进制 Out[15]: ‘616263‘
bytearray
- bytearray是bytes的可变版本
- str和bytes是不可变的
- bytes为什么需要一个可变的版本?
- 图片处理, 修改几个像素的时候, bytes无法原地修改, 如果一个图片3M修改1000次就需要3G的内存, bytearray为了针对这种场景的。大对象的二进制文件做一些原地处理。
- str为什么没有一个可变版本?
- 因为str没有那么大的对象,如果有, 可以先转换为bytearray, 然后再进行处理, 所以不需要。
- 相对于bytes来说, 多了insert, append, extend, pop, remove, clear, reverse原地修改的方法。
- 为什么bytearray插入的字节必须是int
- 因为bytearray它操作的是单个字节
- python没有byte这种类型, 但是byte都可以用int表示。
- 但并不是所有的int可以
- int必须在0 ~ 256这个范围内, 即8位无符号整数。例如b.append(10000000000)就会报错
In [16]: b = b‘abc‘ In [17]: b[1] = b‘B‘ # 不可变的情况在这 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-17-77f7c5b425ec> in <module>() ----> 1 b[1] = b‘B‘ TypeError: ‘bytes‘ object does not support item assignment In [176]: b = bytearray(b) In [20]: b[1] = int(b‘B‘.hex(), 16) # bytearray可变的地方 In [21]: b Out[21]: bytearray(b‘aBc‘) bytearray是可变的 bytes为什么需要一个可变的版本? 图片处理, 修改几个像素的时候, bytes无法原地修改, 如果一个图片3M修改1000次就需要3G的内存, bytearray为了针对这种场景的。大对象的二进制文件做一些原地处理。 str为什么没有一个可变版本? 因为str没有那么大的对象,如果有, 可以先转换为bytearray, 然后再进行处理, 所以不需要。 相对于bytes来说, 多了insert, append, extend, pop, remove, clear, reverse原地修改的方法。 并且支持索引操作 In [23]: b.append(b‘b‘) # insert, append, remove, count参数必须是int --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-23-ac0cb45348e8> in <module>() ----> 1 b.append(b‘b‘) TypeError: an integer is required 为什么bytearray插入的字节必须是int 因为bytearray它操作的是单个字节 python没有byte这种类型, 但是byte都可以用int表示。 但并不是所有的int可以 In [24]: b.append(10000000000000000000000000000000000000000000000000000000000000000000) # int必须在0 ~ 256这个范围内, 即8位无符号整数。 --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-24-2897620e98cd> in <module>() ----> 1 b.append(10000000000000000000000000000000000000000000000000000000000000000000) ValueError: byte must be in range(0, 256)