随着 Python 3 的出现,bytes 类型成为存储和处理二进制数据的主要类型,与字符串 (str) 分开。在 Python 2 中,字符串 (str) 可以包含文本和字节,这导致在处理不同编码的数据时经常出现错误。
在日常编程中,我们常常会遇到在文本信息上下文之外传输和存储数据的任务——例如处理文件、网络请求和交换协议。为此,需要一种明确、方便和安全的类型,清楚地区分字节序列与字符串数据。
Python 中的 bytes 类型存储不可变的字节序列(0 到 255 之间的整数)并且可以通过字节文字(带有前缀 b)或通过显式类型转换来创建。为了在字符串 (str) 和字节 (bytes) 之间安全和可预测的交互,使用 .encode() 和 .decode() 方法。在处理文件、网络和各种二进制协议时,bytes 是主要选择。
代码示例:
# 创建 bytes 对象 b = b'hello' # 通过文字 b2 = bytes([104, 101, 108, 108, 111]) # 从整数列表 # 转换 str <=> bytes text = '文本' bin_text = text.encode('utf-8') # str -> bytes back = bin_text.decode('utf-8') # bytes -> str # 文件示例 with open('file.bin', 'rb') as f: data = f.read() # data: bytes
关键特点:
可以将 bytes 和 str 连接到一个变量吗?
不可以,使用 + 或 f-字符串连接是无效的:如果尝试执行 b'abc' + 'def',将引发 TypeError。需要显式地转换类型。
bytes 和 bytearray 有什么区别?
bytes 是不可变类型,即内容创建后无法更改。bytearray 是可变版本,支持在原地修改字节的方法。
b = bytes([1, 2, 3]) # 不可变 ba = bytearray([1, 2, 3]) # 可变 ba[0] = 99 # OK b[0] = 99 # TypeError
如何知道字符串在通过 encode() 转换时会占用多少字节?
字节数量依赖于编码。例如,对于 'abc' 在 utf-8 中是 3 字节,而 '你好' 是 12 字节。只有在调用 encode() 后,可以通过 len() 来确定准确的大小:
s = '你好' # 2 个字 b = s.encode('utf-8') # 12 字节 print(len(b)) # 12
开发者以 'rb'(字节模式)读取文件,并试图直接将其作为字符串处理:
with open('file.txt', 'rb') as f: for line in f: print(line.strip()) # line: bytes
优点:
缺点:
开发者通过 decode() 处理字节流,引入编码控制:
with open('file.txt', 'rb') as f: for line in f: print(line.decode('utf-8').strip())
优点:
缺点: