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)