核心结论:前缀"b"用于创建字节串对象,它以二进制形式存储数据,是Python处理文件I/O、网络通信等底层操作的基石。
官方名称:字节串
核心功能:表示不可变的二进制数据序列(0-255的整数序列)。
语法形式:在字符串引号前加"b"或"B"
|
1 2 3 |
b'hello' # 字节串 b"world" # 同上 B'test' # 同上 |
| 维度 | 普通字符串 (str) | 字节串 |
|---|---|---|
| 存储内容 | Unicode字符 | 原始字节数据(0-255) |
| 长度单位 | 字符数 | 字节数 |
| 编码 | 已经解码,无需编码 | 需要指定编码才能转为文本 |
| 可打印性 | 直接显示字符 | 显示转义形式(如b'\xe4\xb8\xad') |
| 不可变性 | 不可变 | 不可变 |
| 类型检查 | type('') is str | type(b'') is bytes |
本质区别示例:
|
1 2 3 4 |
s = '中' # 长度1,包含一个Unicode字符 b = b'\xe4\xb8\xad' # 长度3,包含3个字节(UTF-8编码) print(len(s)) # 1 print(len(b)) # 3 |
读写图片、音频、视频、压缩文件等非文本文件时,必须用字节串:
|
1 2 3 4 |
with open('image.jpg', 'rb') as f: # 注意'rb'表示二进制读 data = f.read() # 返回bytes对象 with open('copy.jpg', 'wb') as f: f.write(data) |
网络协议传输的是原始字节流,而非文本:
|
1 2 3 4 5 6 |
import socket sock = socket.socket() sock.connect(('example.com', 80)) request = b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' sock.sendall(request) # 必须发送bytes response = sock.recv(4096) # 返回bytes |
加密算法处理的是二进制数据:
|
1 2 3 4 |
import hashlib md5 = hashlib.md5() md5.update(b'secret') # 必须传入bytes print(md5.hexdigest()) |
|
1 2 3 4 5 |
b'hello' # 单引号 b"world" # 双引号 b'''multi''' # 三单引号 B"""multi""" # 三双引号 b'\xe4\xb8\xad' # 转义序列 |
|
1 2 |
b'中文字符' # ? SyntaxError: bytes can only contain ASCII literal b'\xe4\xb8\xad' # ? 正确:用十六进制表示UTF-8编码 |
|
1 2 |
'text' + b'bytes' # ? TypeError: can't concat str to bytes b'text' + b'bytes' # ? 正确 |
|
1 |
b'hello {}'.format('world') # ? 字节串不支持.format() |
|
1 2 3 4 5 6 7 8 |
# 方法1:encode() text = '你好世界' byte_data = text.encode('utf-8') # b'\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c' # 方法2:bytes构造函数 byte_data = bytes(text, 'utf-8') byte_data = bytes(text, encoding='utf-8') # 方法3:bytes字面量(仅限ASCII) byte_data = b'hello' |
|
1 2 3 4 5 6 7 8 |
# 方法1:decode() text = byte_data.decode('utf-8') # '你好世界' # 方法2:str构造函数 text = str(byte_data, 'utf-8') text = str(byte_data, encoding='utf-8') # 处理解码错误 text = byte_data.decode('utf-8', errors='ignore') # 忽略错误字符 text = byte_data.decode('utf-8', errors='replace') # 用?替换 |
|
1 2 3 4 5 6 7 |
b'hello'.upper() # ? 支持(仅ASCII) b'hello'.lower() # ? 支持(仅ASCII) b'hello'.strip() # ? 支持 # ? 以下操作不支持或不按预期工作: b'hello {}'.format('world') # 不支持格式化 b'hello' + 'world' # 不能与str拼接 b'hello'.isalpha() # 非ASCII字符行为不同 |
|
1 2 3 4 |
byte_data = b'hello \xe4\xb8\xad' text = byte_data.decode('utf-8') text = text.upper() # 使用str的方法 byte_result = text.encode('utf-8') |
|
1 2 3 4 5 |
b'hello'.find(b'e') # ? 支持 b'hello'.replace(b'l', b'x') # ? 支持 b'hello'.split(b'e') # ? 支持 b'abc'.hex() # ? 转为十六进制字符串 bytes.fromhex('616263') # ? 从十六进制创建 |
|
1 2 3 4 5 6 7 8 9 10 |
def copy_binary_file(src, dst, chunk_size=8192): """高效复制二进制文件""" with open(src, 'rb') as f_src, open(dst, 'wb') as f_dst: while True: chunk = f_src.read(chunk_size) # 读取bytes块 if not chunk: break f_dst.write(chunk) # 使用示例 copy_binary_file('original.jpg', 'backup.jpg') |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import socket def simple_http_request(host, path='/'): """发送简单的HTTP GET请求""" # 构建HTTP请求(必须是bytes) request = f"GET {path} HTTP/1.1\r\nHost: {host}\r\n\r\n" request_bytes = request.encode('utf-8') sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, 80)) try: sock.sendall(request_bytes) response = b'' while True: chunk = sock.recv(4096) if not chunk: break response += chunk # 分离头部和主体 header, _, body = response.partition(b'\r\n\r\n') print("Response Header:") print(header.decode('utf-8', errors='ignore')) return body finally: sock.close() # 使用示例 content = simple_http_request('example.com', '/') |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import hashlib def calculate_file_hash(filepath, algorithm='md5'): """计算文件的哈希值""" hash_func = hashlib.new(algorithm) with open(filepath, 'rb') as f: # 二进制模式读取 while True: chunk = f.read(8192) # 分块读取bytes if not chunk: break hash_func.update(chunk) return hash_func.hexdigest() # 使用示例 print(f"MD5: {calculate_file_hash('document.pdf', 'md5')}") print(f"SHA256: {calculate_file_hash('document.pdf', 'sha256')}") |