8.二進制序列類型——bytes,bytearray,memoryview
bytes和bytearray是核心內置類型中用於操作二進制數據的存在。而memoryview是用來支持它們的存在,該類型使用緩衝器協議訪問其他二進制對象的內存,從而跳過複製操作,獲取數據。附帶提及一下,array模塊支持基本數據類型(比如32位整型和IEEE754定義的雙精度浮點數)的高效存儲。
8.1字節(bytes)對象
字節對象是由一系列單個字節構成的不可變序列。由於許多主流的二進制協議都是基於ASCII文本編碼,因此字節對象提供了許多方法專門處理基於ASCII編碼的數據,也提供了一些將二進制與字符串關聯的方法。
class bytes([source[, encoding[, errors]]])
首先,字節文字的語法與字符串文字的語法基本相同,只是添加了b前綴,例如:
1.單引號:b‘ stillallows embedded “double” quotes’ (單引號中允許嵌入雙引號)
2.雙引號:b” still allows embedded ‘single’ quotes” (雙引號中允許嵌入單引號)
3.三引號:b‘’’ 3 single quotes’’’,b”””3 double qutotes”””
在字節文字中只有ASCII字符被允許這樣操作。任何值超過127的二進制值必須經由適當的轉義序列轉化爲字節文字。與字符串文字一樣,字節文字也可以使用r前綴來禁用轉義序列的對其的操作。儘管字節文字和字節表達式是基於ASCII文本,但字節對象的實際行爲卻與不可變整型序列類似,並且,序列中的每個值必須遵循諸如0<=x<256的限制(超出本限制會產生ValueError)。
除了文字形式外,字節對象也可以通過以下方法創建:
1. 爲一個空字節對象指定長度,如:bytes(10)
2. 從一個整型迭代器創建,如:bytes(range(20))
3. 從寄存器協議中賦值一個已存在的二進制數據,如:bytes(obj)
classmethodfromhex(string)
該字節類方法返回一個字節對象,數據由給出的obj字符串對象編碼而來。該字符串要求每字節數據中包含兩個十六進制數,此外其中的ASCII空格會被忽略。
hex()
返回一個字符串對象,要求實例中每字節包含兩個十六進制數。
8.2 字節數組(bytearray)對象
字節數組對象是字節對象的可變副本。
class bytearray([source[, encoding[, errors]]])
由於沒有專用語法用於bytearray對象,因此需要通過調用構造器來對其進行構造:
1. 創建一個空的實例,例如:bytearrary()
2. 創建一個零填充的符合給定長度要求的實例,例如:bytearrary(10)
3. 從整數迭代器中構造,例如:bytearrary(range(20))
4. 通過緩衝區協議複製已存在的二進制數據,例如:bytearray(b’Hi!’)
字節數組對象是可變對象,它支持可變序列操作以及字節對象的共有操作和Bytes and Bytearrary Operations中的字節數組操作。
由於兩個十六進制數字精確對應一個字節,因此十六進制數字被廣泛應用於標準描述二進制數據。相應的,在這種格式下,字節數據類型有自己額外的類方法用於讀取數據:
classmethodfromhex(string)
該類方法返回一個字節數組對象,數據由string參數攜帶的數據編碼而來。string對應的字符串應當每字節包含兩個十六進制數,空格不計入數據中。
此外,系統也提供了一個反函數,將實例中的字節數據轉化爲兩個十六進制數:
hex()
將實例中每個字節轉化爲兩個十六進制數
儘管字節數組對象是整數序列,但是要注意的是,對於字節數組對象b,b[0]是一個整型數,但b[0:1]卻是一個長度爲1的字節數組對象。
8.3字節和字節數組操作
所有的字節和字節數組對象都支持通用序列操作。並且,它們的交互操作不僅支持相同的數據類型,也支持任何類似於字節的對象。由於這樣的高靈活性,他們可以在操作中自由混合而不會造成錯誤。然而需要注意的是,返回的結果類型需要依據操作而論。。
8.4內存視圖(memory views)
memoryview對象允許允許Python代碼可以免去複製過程,直接從支持緩衝協議的對象內部提取數據。
classmemoryview(obj)
參考obj創建一個memoryview對象。obj必須支持緩衝協議,當其爲內置對象時應該爲字節或字節數組對象,
__eq__(exporter)
如果內存視圖和導出器的形狀相同,並且所有相應的值在使用結構語法解釋操作數的相應格式代碼時相等,則它們是相等的。
tobytes()
將緩衝器內的數據以字節字符串的格式輸出。
>>> m =memoryview(b"abc")
>>> m.tobytes()
b'abc'
>>> bytes(m)
b'abc'
tolist()
將緩衝器內的元素作爲列表元素輸出。
>>> memoryview(b'abc').tolist()
[97, 98, 99]
>>> importarray
>>> a= array.array('d', [1.1,2.2,3.3])
>>> m=memoryview(a)
>>> m.tolist()
[1.1, 2.2, 3.3]
release()
釋放由memoryview對象公開的底層緩衝區。
>>> m =memoryview(b'abc')
>>> m.release()
>>> m[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operation forbidden on released memoryview object