Python/字節數組
Buffer Protocol是特定的Python對象,包裝了訪問內存數組或者緩衝區。包括內置類型:
- bytes是只讀字節數組。
- bytearray是可讀寫字節數組。
- array.array
a=b"abc" #创建bytes对象 bytes("汉字","utf-8") #创建bytes对象,解码方式为utf-8 b=bytearray(b"abc") #创建bytearray对象
與字符串一樣,支持append、extend、upper等方法,加法、乘法等運算。
bytes
編輯class bytes([source[, encoding[, errors]]])構造函數,如
a=b'still allows embedded "double" quotes'
其他構造函數:
bytes(10) bytes(range(20)) bytes(otherBytesObj)
類方法:
- fromhex(string):以16進制解碼一個字符串,其中的空白符被忽略。如bytes.fromhex('2Ef0 F1f2 ')
- hex([sep[, bytes_per_sep]]):把內容編碼為16進制數字組成的字符串。bytes_per_sep控制分隔符出現在哪個字節,正值從右數,負值從左數
bytearray
編輯bytearray是可變的(mutable)版本,與只讀的bytes對應。
構造函數:
bytearray() bytearray(10) bytearray(range(20)) bytearray(b'Hi!')
有類似的類方法fromhex和hex
bytes和bytearray共同的一些類方法
編輯- count(sub[, start[, end]]):返回不重疊的子串sub的出現次數
- removeprefix(prefix, /):去除跟定的前綴子串
- removesuffix(suffix, /)
- decode(encoding='utf-8', errors='strict'):返回從給定字節解碼的字符串
- endswith(suffix[, start[, end]])
- find(sub[, start[, end]]):返回子串sub最小出現的下標值。未找到返回-1
- index(sub[, start[, end]]):類似find方法,但未找到拋出異常
- join(iterable):返回一個新的對象
- maketrans(from, to):這個靜態方法返回一個可用於 bytes.translate() 的轉換表,它將把 from 中的每個字符映射到 to 中相同位置的字符; from 和 to 必須都是類似字節對象(bytes-like objects)並且具有相同的長度。
- partition(sep):在第一次出現 sep 時拆分序列,並返回一個 3 元組,其中包含分隔符之前的部分、分隔符本身或其 bytearray 副本以及分隔符之後的部分。 如果未找到分隔符,則返回一個包含原始序列副本的 3 元組,後跟兩個空字節或 bytearray 對象。
- replace(old, new[, count]):如果給出參數count,只對前面count次替換。
- rfind(sub[, start[, end]])
- rindex(sub[, start[, end]])
- rpartition(sep)
- startswith(prefix[, start[, end]])
- translate(table, /, delete=b):返回新對象——刪除了參數 delete 中出現的所有字節,其餘字節通過給定的轉換表映射,該轉換表必須是長度為 256 的字節對象。可以使用 bytes.maketrans() 方法創建轉換表。對於只刪除字符的翻譯,將 table 參數設置為 None。
- ljust(width[, fillbyte]):返回新對象,在左側填充字符,如果原對象字節長度小於width
- lstrip([chars]):默認從左側開頭位置刪除空白符。該函數刪除參數chars中所有字符的任意組合;而removeprefix方法只刪除子串。
- rjust(width[, fillbyte])
- rsplit(sep=None, maxsplit=- 1)
- rstrip([chars])
- split(sep=None, maxsplit=- 1)
- strip([chars])
- capitalize()
- expandtabs(tabsize=8):返回序列的副本,其中所有制表符被指定個數的空格符替換
- isalnum()
- isalpha()
- isascii()
- isdigit()
- islower()
- isspace()
- istitle()
- isupper()
- lower()
- splitlines(keepends=False):返回一個list
- swapcase()
- title()
- upper()
- zfill(width):左側零填充
print(格式化參數),轉換說明符包含兩個或多個字符並具有以下組件,這些組件必須按此順序出現:
- '%' 字符,標記說明符的開始。
- 映射鍵(可選),由帶括號的字符序列組成,為後續字典變量中的key
- 轉換標誌(conversion flag,可選),影響某些轉換類型的結果。'#'值轉換使用「alternate form」;'0'表示零填充數值;'-'表示左對齊;' '產生有符號轉換;'+'產生帶正負號的轉換。
- 最小字段寬度(可選)。如果指定為「*」(星號),則從值中元組的下一個元素讀取實際寬度,並且要轉換的對象位於最小字段寬度和可選精度之後。
- 精度(可選),以「.」形式給出(點)後跟精度。如果指定為 '*'(星號),則從 values 中元組的下一個元素讀取實際精度,並且要轉換的值位於精度之後。
- 長度修飾符(可選),可為h, l, L。但Python忽略它們。
- 轉換類型。基本類似C語言的sprintf函數。's' 或'b' 表示字節(任何遵循緩衝區協議或具有 __bytes__() 的對象)。'r' 或'a' 表示字節(使用 repr(obj).encode('ascii', 'backslashreplace') 轉換任何 Python 對象)。
例如:
print(b'%(language)s has %(number)03d quote types.' %{b'language': b"Python", b"number": 2})
array.array
編輯如果需要使用數組,需要如下:
import array
a = array.array('h', [0, 1, 2, 3])
構造函數class array.array(typecode[, initializer])創建一個由 typecode限制類型的新數組,並由initializer的值進行初始化。實際上,會根據initializer的情況調用本類的fromlist()、 frombytes() 或 fromunicode() 方法將初始元素添加到數組中,或者將可迭代對象作為initializer傳給 extend() 方法。
本類的方法或屬性:
- array.typecode:用於創建數組的類型碼字符。
- array.itemsize:在內部表示中一個數組項的字節長度。
- array.append(x):添加一個值為 x 的新項到數組末尾。
- array.buffer_info():返回一個元組 (address, length) 以給出用於存放數組內容的緩衝區元素的當前內存地址和長度。 以字節表示的內存緩衝區大小可通過 array.buffer_info()[1] * array.itemsize 來計算。
- array.byteswap():對所有數組項做大小端序交換。 此方法只支持大小為 1, 2, 4 或 8 字節的值;對於其他值類型將引發 RuntimeError。 它適用於從不同字節序機器所生成的文件中讀取數據的情況。
- array.count(x):返回 x 在數組中的出現次數。
- array.extend(iterable):將來自 iterable 的項添加到數組末尾。 如果 iterable 是另一個數組,它必須具有 完全 相同的類型碼;否則將引發 TypeError。 如果 iterable 不是一個數組,則它必須為可迭代對象並且其元素必須為可添加到數組的適當類型。
- array.frombytes(s):添加來自字節串的項,將字符節解讀為機器值的數組(相當於使用 fromfile() 方法從文件中讀取數據)。
- array.fromfile(f, n):從 file object f 中讀取 n 項並將它們添加到數組末尾。 如果可用數據少於 n 項,則會引發 EOFError,但可用的項仍然會被插入數組。
- array.fromlist(list):添加來自 list 的項。 這等價於 for x in list: a.append(x),區別在於如果發生類型錯誤,數組將不會被改變。
- array.fromunicode(s):使用來自給定 Unicode 字符串的數組擴展數組。 數組必須是類型為 'u' 的數組;否則將引發 ValueError。 請使用 array.frombytes(unicodestring.encode(enc)) 來將 Unicode 數據添加到其他類型的數組。
- array.index(x[, start[, stop]]):返回最小的 i 使得 i 為數組中首次出現的 x 的索引號。 指定可選參數 start 和 stop 以便在數組的一個子部分內部搜索 x。 如果未找到 x 則會引發 ValueError。
- array.insert(i, x):將值 x 作為新項插入數組的 i 位置之前。 負值將被視為相對於數組末尾的位置。
- array.pop([i]):從數組中移除序號為 i 的項並將其返回。 可選參數值默認為 -1,因此默認將移除並返回末尾項。
- array.remove(x):從數組中移除首次出現的 x。
- array.reverse():反轉數組中各項的順序。
- array.tobytes():將數組轉換為一個機器值數組並返回其字節表示(即相當與通過 tofile() 方法寫入到文件的字節序列。)
- array.tofile(f):將所有項(作為機器值)寫入到 file object f。
- array.tolist():將數組轉換為包含相同項的普通列表。
- array.tounicode():將數組轉換為一個 Unicode 字符串。 數組必須是類型為 'u' 的數組;否則將引發 ValueError。 請使用 array.tobytes().decode(enc) 來從其他類型的數組生成 Unicode 字符串。
memoryview
編輯memoryview對象支持訪問一個滿足緩衝區協議(buffer protocol)的對象的內部數據而無需複製操作。這包括bytes、bytearray、array.array等類型。如:
a=bytearray([0x10,0x11,0x12,0x13,0x14,0x15,0x16]) v=memoryview(a)
內存視圖轉化為其它類型,可用tobytes、tolist,或者cast方法,或者struct.unpack方法。
len(view)等於tolist的長度
view.ndim = 0則長度為1。view.ndim = 1則長度為view中元素個數。
itemsize特性給出單個元素的字節數。
調用內存視圖的release函數,可以使得原對象實例恢復全部操作能力。
memoryview支持切片和索引操作。
memoryview可修改內容。如:
data = bytearray(b'abcefg') v = memoryview(data) v[1:4] = b'123' #data内容变为 bytearray(b'z123fg')
memoryview是按維度和元素值比較相等,如
a = array.array('I', [1, 2, 3, 4, 5]) b = array.array('d', [1.0, 2.0, 3.0, 4.0, 5.0]) c = array.array('b', [5, 3, 1]) x = memoryview(a) y = memoryview(b) x == a == y == b # 为True
其它方法有:
- tobytes(order=None):參數值可以為{『C』, 『F』, 『A』}分別表示C語言、Fortran語言、物理序。
- hex([sep[, bytes_per_sep]]):返回十六進制表示的字符串。
- tolist()
- toreadonly():返回只讀的memoryview
- release():釋放基礎數據。當前memoryview不再有效。
- cast(format[, shape]):創建一個新的memoryview,但基礎buffer數據不變。如:
import struct buf = struct.pack("i"*12, *list(range(12))) x = memoryview(buf) y = x.cast('i', shape=[2,2,3]) y.tolist() #结果为[[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
memoryview的只讀屬性:
- obj:返回基礎buffer的對象
- nbytes:總字節數
- readonly:是否只讀
- format
- itemsize
- ndim:多維數組的維數
- shape:多維數組的維度的元組表示
- strides:多維數組各維度的字節步長
- c_contiguous
- f_contiguous
- contiguous
格式說明
編輯字符 | 字節序 | 尺寸 | 對齊 |
---|---|---|---|
@ | native | native | native |
= | native | standard | none |
< | 小尾序 | standard | none |
> | 大尾序 | standard | none |
! | 網絡序 | standard | none |
Format | C Type | Python type | Standard size | 注釋 |
---|---|---|---|---|
x | pad byte | no value | ||
c | char | bytes of length 1 | 1 | |
b | signed char | integer | 1 | |
B | unsigned char | integer | 1 | |
? | _Bool | bool | 1 | C99引入的類型。返回值是 True或False |
h | short | integer | 2 | |
H | short | integer | 2 | |
i | int | integer | 4 | |
I | unsigned int | integer | 4 | |
l | long | integer | 4 | |
L | unsigned long | integer | 4 | |
q | long long | integer | 8 | |
Q | unsigned long long | integer | 8 | |
n | ssize_t | integer | ||
N | size_t | integer | ||
e | 半精度 | float | 2 | |
f | float | float | 4 | |
d | double | float | 8 | |
s | char[] | bytes | 整數後跟s,表示字節序列長度。默認為1。會自動截斷或補0字節 | |
p | char[] | bytes | Pascal string | |
P | void * | integer |
數字後面跟隨格式字符,表示該格式字符重複的次數。例如:'4h'等價於'hhhh'