
本文介绍解决 pandas `read_excel` 接收字节对象时触发弃用警告的正确方法,核心是使用 `bytesio` 将字节流封装为文件类对象,确保代码兼容最新版本并符合官方推荐实践。
当从云存储(如 Azure Blob Storage、AWS S3)或内存中读取 Excel 文件时,常通过 .readall() 或 .read() 获取 bytes 类型数据。然而,自 Pandas 2.1+ 起,直接将 bytes 传入 pd.read_excel() 已被明确标记为 deprecated,会触发如下警告:
FutureWarning: Passing bytes to 'read_excel' is deprecated and will be removed in a future version. To read from a byte string, wrap it in a `BytesIO` object.
✅ 正确做法是:将原始字节数据包装为 io.BytesIO 对象,使其具备文件类接口(支持 seek()、read() 等),从而被 read_excel 安全识别为合法输入源。
以下是标准、健壮的实现方式:
from io import BytesIO import pandas as pd # 假设 blob_data 是类似 Azure BlobClient 的响应对象 excel_bytes = blob_data.readall() # type: bytes df = pd.read_excel(BytesIO(excel_bytes), engine='openpyxl')
? 关键说明:
- BytesIO(excel_bytes) 创建了一个可随机访问的内存文件对象,read_excel 内部可正常调用其 seek(0) 重置读取位置(这对多 sheet 或重复解析至关重要);
- engine='openpyxl' 保持不变,适用于 .xlsx 文件;若处理 .xls,可改用 'xlrd'(注意:xlrd ≥ 2.0 仅支持 .xls,不再支持 .xlsx);
- 此方案无需额外依赖新库,完全基于 Python 标准库 + pandas,兼容性强、无性能损耗。
⚠️ 注意事项:
- 避免重复调用 blob_data.readall()(如多次封装 BytesIO),因部分 blob SDK 的 readall() 不可重入;
- 若数据量极大(>100MB),建议改用流式下载 + tempfile.NamedTemporaryFile 临时落盘(需权衡 I/O 开销与内存压力);
- 使用 BytesIO 后,无需手动关闭——它属于内存对象,作用域结束即自动释放。
? 总结:这不是 Pandas 的 bug,而是 API 设计演进。BytesIO 封装是官方唯一推荐的替代方案,简洁、安全、向后兼容。坚持此模式,即可彻底消除弃用警告,并为未来版本升级做好准备。










