如何编写无需six库、兼容Python2.7+/3.6+的CSV读取函数
Python2/3 兼容无依赖CSV读取函数实现
问题根因
出现跨版本报错的核心原因是Python2和Python3的csv模块对输入输出流的类型要求存在差异:
- Python 2.x 版本的
csv模块仅支持字节流输入输出,需配合BytesIO使用,文件打开无需指定编码 - Python 3.x 版本的
csv模块仅支持Unicode文本流输入输出,需配合StringIO使用,文件打开需指定编码格式
兼容实现代码
无需安装任何第三方依赖,仅用标准库即可实现双版本兼容:
import sys import csv def read_csv(filename): """ Sanitise and read CSV report, compatible with Python 2.7+ and Python 3.6+ """ # lowest number of columns to expect in the header sane_columns = 7 # 按Python版本选择对应的IO类与文件读取逻辑 if sys.version_info.major == 2: from io import BytesIO stream = BytesIO() with open(filename) as csvfile: reader = csv.reader(csvfile) temp_writer = csv.writer(stream) for csv_row in reader: if len(csv_row) >= sane_columns: temp_writer.writerow(csv_row) else: from io import StringIO stream = StringIO() with open(filename, encoding="utf-8") as csvfile: reader = csv.reader(csvfile) temp_writer = csv.writer(stream) for csv_row in reader: if len(csv_row) >= sane_columns: temp_writer.writerow(csv_row) # Move stream back to the start stream.seek(0) dict_reader = csv.DictReader(stream) return dict_reader
关键适配点
- 用标准库
sys.version_info判断运行时Python版本,无额外依赖 - 版本分支分别适配对应版本
csv模块的流类型要求、文件打开参数 - 完全保留原有过滤头部垃圾行的逻辑,不影响原有业务功能
- 所有导入模块均为Python2.7、Python3.6+自带的标准库,无需安装任何pip包
内容的提问来源于stack exchange,提问作者danidar
相关产品推荐
相关产品推荐

