python 二进制序列类型 bytes 和 bytearray
bytes
bytes 定义
bytes是一个不可变序列,用于存储字节数据。bytes对象包含范围在0到255之间的整数序列,通常用于处理二进制数据、文本数据的字节表示、以及网络通信中的原始数据传输。
创建 bytes 对象
使用 b'...' 表示字节字符串,各个字符以 ASCII 对应的单字节值表示。
使用 bytes() 函数将一个字节串或一个可迭代对象转换为 bytes 对象。
# 创建简单的 bytes 对象
data = b'hello'
print(data) # 输出:b'hello'
# 从字符串创建bytes,需要指定编码
b1 = bytes("hello", encoding='utf-8')
print(b1) # 输出:b'hello'
# 从列表创建bytes
b2 = bytes([72, 101, 108, 108, 111]) # 字节序列对应 ASCII 中的 H, e, l, l, o.
print(b2) # 输出:b'Hello'
# 使用bytes()构造函数创建一个指定长度的bytes,内容初始化为null bytes
b3 = bytes(5)
print(b3) # 输出:b'\x00\x00\x00\x00\x00'
bytes 访问和索引
bytes 对象是不可变的,类似于字符串对象。
可以使用索引和切片操作访问 bytes 中的元素。
b = bytes('hello', 'utf-8')
print(b[0]) # 输出: 104
print(b[:3]) # 输出: b'hel'
bytes 与 str 类型的转换
可以使用 encode() 方法将字符串转换为 bytes 对象,使用 decode() 方法将 bytes 对象转换为字符串。
b = bytes('hello', 'utf-8')
s = b.decode('utf-8') # bytes 转 str
print(s) # 输出: hello
s = 'hello world'
b = s.encode('utf-8') # str 转 bytes
print(b) # 输出: b'hello world'
bytes 常用方法
count():计算某个字节在 bytes 中出现的次数。
find():查找某个字节第一次出现的位置。
replace():替换字节,由于 bytes 是不可变的,这会返回一个新的 bytes 对象。
fromhex(string): 是一个类方法,使用 fromhex() 方法从十六进制字符串创建 bytes 对象。通常用于需要手动输入或从文档中解析二进制数据时。
hex(): 用于将 bytes 对象转换为十六进制表示的字符串。这通常用于调试、日志记录或将二进制数据转换为更易于阅读和传输的格式。
b = bytes('hello world', 'utf-8')
print(b.count(108)) # 输出: 3
print(b.find(111)) # 输出: 4
print(b.replace(b'l', b'x')) # 输出: b'hexxo worxd'
# 从十六进制字符串创建 bytes 对象
hex_string = '68656c6c6f'
b = bytes.fromhex(hex_string)
print(b) # 输出: b'hello'
# 将 bytes 对象转换为十六进制字符串
b = bytes('hello', 'utf-8')
hex_str = b.hex()
print(hex_str) # 输出: '68656c6c6f'
bytearray
bytearray 定义
bytearray 类似于 bytes,但是它是可变的字节数组,可以对其进行修改。这意味着你可以在不创建新对象的情况下修改 bytearray 中的元素。这使得 bytearray 非常适合处理需要改变大小或内容的字节数据,例如读取和修改文件、处理网络数据包等。
创建 bytearray
从字符串转换,需要指定编码。
从一个字节序列或列表。
使用 bytearray() 构造函数,可指定初始大小和内容。
# 从字符串创建bytearray,需要指定编码
ba1 = bytearray("hello", encoding='utf-8')
print(ba1) # 输出:bytearray(b'hello')
# 从列表创建bytearray
ba2 = bytearray([72, 101, 108, 108, 111])
print(ba2) # 输出:bytearray(b'hello')
# 使用bytearray()构造函数创建一个指定长度的bytearray,内容初始化为null bytes
ba3 = bytearray(5)
print(ba3) # 输出:bytearray(b'\x00\x00\x00\x00\x00')
修改 bytearray
ba = bytearray('hello', 'utf-8')
print(ba) # 输出: bytearray(b'hello')
ba[0] = 72 # 修改第一个字节
print(ba) # 输出: bytearray(b'Hello')
bytearray 对象与 bytes 对象的转换
可以使用 bytes() 函数将 bytearray 对象转换为不可变的 bytes 对象。
可以使用 bytearray() 构造函数将 bytes 对象转换为可变的 bytearray 对象。
# 将 bytearray 转换为 bytes 对象
data = bytearray(b'hello')
immutable_data = bytes(data)
print(immutable_data) # 输出:b'hello'
# 将 bytes 对象转换为 bytearray
data = b'hello'
mutable_data = bytearray(data)
print(mutable_data) # 输出:bytearray(b'hello')
bytearry 常用方法
append(x): 添加一个元素。
extend(iterable): 扩展bytearray,可以是另一个bytearray、bytes或任何可迭代对象。
pop([index]): 移除指定位置的元素,默认为最后一个,并返回该元素。
replace(old, new): 替换元素。
count(x): 计算某个元素出现的次数。
insert(i, x): 在指定位置 i 插入一个元素 x。
remove(x): 移除 bytearray 中第一次出现的元素 x。
find(sub[, start[, end]]): 从 bytearray 中查找子序列 sub 并返回第一个匹配的索引,如果未找到返回 -1。
reverse():将 bytearray 中的元素顺序反转。这在某些需要调整字节顺序的场景(如端序转换)中非常有用。
clear():用来清空 bytearray 中的所有元素,使其长度变为 0。这个方法在你需要重用但清空数据的 bytearray 对象时非常方便。
hex():将 bytearray 中的数据转换为一个十六进制字符串。这在需要查看或记录二进制数据的文本表示时特别有用。
fromhex():是一个类方法,用于从十六进制字符串创建一个新的 bytearray 对象。这在需要从十六进制编码的文本中解码数据时非常实用。
ba = bytearray('hello world', 'utf-8')
ba.append(33) # 添加 '!' ASCII值
print(ba) # 输出: bytearray(b'hello world!')
ba.extend([46, 46]) # 添加 '..'
print(ba) # 输出: bytearray(b'hello world!..')
print(ba.pop()) # 移除并返回最后一个元素,输出: 46
print(ba) # 输出: bytearray(b'hello world!.')
print(ba.replace(b'o', b'0')) # 替换 'o' 为 '0'. 输出: bytearray(b'hell0 w0rld!.')
ba.insert(3, 101) # Insert 'e' at index 3
print(ba) # 输出: bytearray(b'helelo world!.')
ba.remove(111) # ASCII for 'o'
print(ba) # 输出: bytearray(b'helel world!.')
print(ba.hex()) # 输出: 68656c656c20776f726c64212e
print(ba.find(b"e")) # 输出: 1
ba.reverse()
print(ba) # 输出: bytearray(b'.!dlrow leleh')
ba.clear()
print(ba) # 输出: bytearray(b'')
字符串(str)与字节序列的关系
在Python中,str和bytearray代表了两种不同的数据类型:
字符串 (str): Unicode字符的序列,用于文本处理。Unicode是一个标准,它为世界上大多数书写系统的每一个字符提供了唯一的编号。
字节数组 (bytearray): 可变的字节序列,用于处理二进制数据,如文件数据、网络数据包等。
bytearray 与 str 类型的转换
可以使用 encode() 方法将字符串转换为 bytearray 对象,使用 decode() 方法将 bytearray 对象转换为字符串。
将str转换为bytearray通常是一个两步过程:
编码: 使用str的encode()方法将字符串按照指定编码(如utf-8)转换为bytes。
转换: 将bytes对象转换为bytearray。
# 将str转换为bytearray
s = "Hello, Python!"
encoded_bytes = s.encode('utf-8') # 使用 utf-8 编码字符串为字节序列
ba = bytearray(encoded_bytes) # 转换为 bytearray
print(ba) # 输出: bytearray(b'Hello, Python!')
# 将bytearray转换为str
ba = bytearray(b'Hello, Python!')
decoded_str = ba.decode('utf-8') # 解码为 str
print(decoded_str) # 输出: Hello, Python!
编码和解码
编码是将字符串转换为字节序列的过程,而解码是将字节序列转换回字符串的过程。编码和解码都需要指定字符编码方案,utf-8是最常用的,因为它支持国际化的字符集。
encode() 方法用于将字符串转换为指定的字节序列,根据指定的编码格式将字符串转换为字节码。
decode() 方法用于将字节序列解码为字符串,根据指定的编码格式将字节码转换为字符串。
参考文档
https://docs.python.org/zh-cn/3.12/library/stdtypes.html#/binary-sequence-types-bytes-bytearray-memoryview