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'