字符串與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)