Python bytearray() 语法
bytearray() 是 Python 的一个内置函数 , 它用于表示可变的二进制数据。bytearray 对象是可变的,可以对其中的元素进行添加、删除和修改操作。
正是因为 bytearray 二进制数据可变的特性,bytearray 类型主要应用于需要频繁修改二进制数据的场景。
语法:
bytearray(source, encoding='utf-8', errors='strict')说明:
bytearray() 函数接收以下 3 个参数。
source(必选):操作的对象,可以是以下类型之一。- 当 source 是字符串:必须提供 encoding 参数,将字符串编码为字节序列。
- 当 source 是整数:表示创建一个提供大小的字节数组,所有字节初始化为 0。
- 当 source 是 bytes 对象:返回一个新的 bytearray 对象,内容与原对象相同。
- 当 source 是包含整数的可迭代对象:每个整数必须在 0 到 255 之间,否则会抛出 ValueError。
- 无参数:返回一个空的 bytearray 对象。
encoding(可选,默认值: 'utf-8'):编码类型,当 source 是字符串时,指定编码方式。常见编码包括 'utf-8'、'ascii'、'latin-1' 等。errors(可选,默认值: 'strict'):指定编码错误处理方式,可选值包括:'strict':编码失败时抛出 UnicodeError(默认行为)。'ignore':忽略无法编码的字符。'replace':用 ? 替换无法编码的字符。'xmlcharrefreplace':用 XML 字符引用替换无法编码的字符。'namereplace':用 \N{...} 替换无法编码的字符。'backslashreplace':用 \x... 替换无法编码的字符。
字符串数据 vs 二进制数据
Python 3 最重要的新特性之一,就是对字符串和二进制做了明确的区分。字符串由 str 类型表示,它是以 “字符” 为单位进行处理。二进制由 bytes 类型或 bytearray 类型表示,它是以 “字节” 为单位进行处理。
与不可变的 bytes 类型不同,bytearray 类型是一个可变的序列对象。它允许我们在原地直接修改字节流,而不需要每次修改都去创建一个新的对象。bytearray 类型通常用于需要频繁拼接或修改二进制数据的场景,比如图像处理、自定义网络协议缓存等。bytearray 对象是通过 bytearray() 函数生成的。
Python 不会以任何隐式的方式来混用 str 和二进制流(无论是 bytes 还是 bytearray)。因此,我们不能将字符串和字节流直接进行拼接,也无法在字节流中直接搜索字符串,更不能将字符串直接作为需要字节流的函数参数。它们之间必须通过显式的编码(encode)和解码(decode)来进行相互转换。
Python bytearray() 摘要
| 使用频率 | 中 |
|---|---|
| 官方文档 | 查看 |
Python bytearray() 示例
接下来,我们通过几个简单的例子来讲解一下 Python bytearray() 函数是如何使用的。
示例 1:bytearray() 将字符串转换为二进制数据
result = bytearray('lvyenet', encoding='utf-8')
print(result)
print(type(result))运行结果如下。
bytearray(b'lvyenet')
<class 'bytearray'>分析:
当 bytearray() 操作对象是一个字符串时,要求显式提供 encoding。对于上面例子来说,如果只是写成 result = bytearray('lvyenet'),则会报以下的错误。
(报错)TypeError: string argument without an encoding此外需要清楚的是,下面 2 种方式是等价的。
# 方式 1
result = bytearray('lvyenet', encoding='utf-8')
# 方式 2
result = bytearray('lvyenet', 'utf-8')注意: 不能直接使用 b'lvyenet' 来创建 bytearray 对象,因为这种语法糖创建的是不可变的 bytes 对象。
示例 2:bytearray() 创建指定大小的二进制数据
result = bytearray(5)
print(result)运行结果如下。
bytearray(b'\x00\x00\x00\x00\x00')示例 3:bytearray() 将可迭代对象转换为二进制数据
nums = [1, 2, 3, 4, 5]
result = bytearray(nums)
print(result)运行结果如下。
bytearray(b'\x01\x02\x03\x04\x05')示例 4:bytearray() 创建空的 bytearray 对象
result = bytearray()
print(result)运行结果如下。
bytearray(b'')bytearray 常用操作
对于 bytearray 对象来说,它常用的操作如下表所示。其中,obj 是一个 bytearray 对象。
| 操作 | 说明 |
|---|---|
| len(obj) | 获取 bytearray 对象中的字节数 |
| obj[index] | 获取 bytearray 对象索引为 index 的字节 |
| obj.append(x) | 在 bytearray 对象末尾添加一个字节 x |
| obj.extend(iterable) | 在 bytearray 对象末尾添加多个字节 |
| obj.insert(i, x) | 在 bytearray 对象索引 i 处插入一个字节 x |
| obj.pop([i]) | 移除并返回 bytearray 对象索引 i 处的字节,默认移除最后一个字节 |
| obj.remove(x) | 移除 bytearray 对象中第一个值为 x 的字节 |
| obj.clear() | 清空 bytearray 对象中的所有字节 |
| obj.count(sub, start, end) | 获取 bytearray 对象中子序列 sub 出现次数 |
| obj.find(sub, start, end) | 查找 bytearray 对象中子序列 sub 出现的位置 |
| obj.hex() | 返回 bytearray 对象的十六进制表示 |
bytearray 类型并没有想象中那么复杂,它只在特定场合下才会用到。大多数情况下,我们只需要它和字符串类型是如何相互转换的即可,也就是:
- bytearrayObject.decode('编码类型'):将二进制数据转换为字符串。
- strObject.encode('编码类型'):将字符串编码为 bytearray 二进制数据(注意:如果直接使用 strObject.encode('编码类型'),得到的是不可变的 bytes 对象,而不是 bytearray 对象)。
bytes()、bytearray() 与 memoryview() 的区别
bytes()、bytearray() 与 memoryview() 这 3 个函数都可以用于操作二进制数据,它们之间的区别如下:
bytes():创建的对象是不可变的,适合表示不可变的二进制数据。bytearray():创建的对象是可变的,适合需要频繁修改的二进制数据。memoryview():创建内存视图,用于直接操作二进制数据。
| 函数 | 可变性 | 用途 |
|---|---|---|
| bytes() | 不可变 | 存储静态二进制数据(如文件内容) |
| bytearray() | 可变 | 频繁修改的二进制数据(如协议解析) |
| memoryview() | 内存视图 | 零拷贝操作缓冲区(如处理大型二进制数据) |
示例 5:bytearray() 创建空的 bytearray 对象
# 创建一个 bytearray 对象
b_arr = bytearray(b'lvye')
print(b_arr)
# 修改第一个字节
b_arr[0] = 76
print(b_arr)运行结果如下。
bytearray(b'lvye')
bytearray(b'Lvye')分析:
在这个例子中,b_arr[0] = 76 表示修改第一个字节。其中,'l' 的 ASCII 码是 108,我们把它改成大写 'L' 的 ASCII 码 76。
与不可变的 bytes 对象不同,bytearray 对象支持原地的增删改操作。我们可以直接通过索引来修改特定位置的字节值(注意:传入的必须是 0 到 255 之间的整数)。
