python中的bytearray函数用于创建一个可变的字节序列对象,它和不可变的bytes类型同属于字节序列相关类型,但是支持直接修改内部元素,在处理需要频繁变更字节内容的场景时非常实用。

bytearray的基本定义与参数
bytearray函数的语法格式如下:
# bytearray函数语法 bytearray([source[, encoding[, errors]]])
它的参数说明如下:
- 如果不传入任何参数,会创建一个长度为0的空bytearray对象
- 如果传入整数n,会创建一个长度为n的bytearray对象,所有元素初始化为0
- 如果传入字符串,需要同时指定encoding参数,会将字符串按照指定编码转为字节序列
- 如果传入可迭代对象,要求可迭代对象中的元素都是0-255之间的整数,会将这些整数作为字节值创建对象
bytearray和bytes的核心区别
两者都属于字节序列类型,但是核心差异在于可变性,具体对比如下:
| 对比项 | bytes | bytearray |
|---|---|---|
| 可变性 | 不可变,创建后无法修改内部元素 | 可变,可以直接修改、添加、删除内部元素 |
| 修改操作 | 不支持直接赋值修改,修改需要创建新的bytes对象 | 支持通过索引赋值、append、extend等方法修改 |
| 适用场景 | 不需要变更的字节数据,比如固定的二进制标识 | 需要频繁修改的字节数据,比如网络数据拼接、二进制文件修改 |
bytearray的常见用法示例
1. 创建bytearray对象
不同参数下的创建方式示例如下:
# 创建空bytearray
empty_ba = bytearray()
print(empty_ba) # 输出:bytearray(b'')
# 传入整数创建指定长度的bytearray
len_ba = bytearray(5)
print(len_ba) # 输出:bytearray(b'x00x00x00x00x00')
# 传入字符串创建
str_ba = bytearray("hello", encoding="utf-8")
print(str_ba) # 输出:bytearray(b'hello')
# 传入可迭代整数对象创建
iter_ba = bytearray([97, 98, 99])
print(iter_ba) # 输出:bytearray(b'abc')
2. 修改bytearray内部元素
因为bytearray是可变的,所以可以直接通过索引修改元素,也可以通过内置方法调整内容:
ba = bytearray("hello", encoding="utf-8")
# 通过索引修改单个元素
ba[0] = 72 # 72是字符H的ASCII值
print(ba) # 输出:bytearray(b'Hello')
# 使用append方法添加单个字节
ba.append(33) # 33是!的ASCII值
print(ba) # 输出:bytearray(b'Hello!')
# 使用extend方法拼接其他字节序列
ba.extend(b"world")
print(ba) # 输出:bytearray(b'Hello!world')
3. 实际应用场景
bytearray在网络编程和二进制文件处理中非常常用,比如拼接网络接收的分片数据:
# 模拟接收分片的网络数据,拼接为完整数据
recv_data = bytearray()
# 模拟三次接收分片
recv_data.extend(b"first_")
recv_data.extend(b"second_")
recv_data.extend(b"third")
print(recv_data.decode("utf-8")) # 输出:first_second_third
另外在处理二进制文件时,如果需要修改文件中的部分字节内容,也可以先将文件内容读取为bytearray,修改后再写回文件,避免频繁创建新的字节对象带来的性能开销。
注意事项
使用bytearray时需要注意,赋值给索引的元素必须是0到255之间的整数,否则会抛出ValueError异常。同时bytearray对象可以直接转为bytes对象,使用bytes()函数即可,转换后会得到不可变的字节序列。
bytearray的可变特性让它在需要频繁操作字节内容的场景下比bytes更高效,但是如果是固定不变的字节数据,优先使用bytes可以避免意外的修改。