Python bytearray() 函数

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 对象。

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()
函数 可变性 用途
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 之间的整数)。

上一篇: bytes()

下一篇: memoryview()

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号