# 聊聊Python里的CSV模块有过两年Python开发经验的人大概率都用过CSV文件。这东西看起来简单但用起来有不少门道。它到底是个什么东西CSV全称是Comma-Separated Values逗号分隔值。就是把表格数据用纯文本存起来。每一行是一行数据每个字段用逗号隔开。比如姓名,年龄,城市 张三,28,北京 李四,32,上海以前我在一家电商公司干活后端服务之间传数据用的就是CSV。当时觉得这玩意儿low后来才明白csv在很多场景下确实是最合适的选择——简单、通用、任何编辑器都能打开。有一点值得提很多人以为CSV就真的只靠逗号分隔。实际上Python的csv模块考虑了更复杂的情况比如字段里包含逗号该怎么办字段本身有换行符怎么办。标准做法是用引号把字段包起来或者用双引号转义。它能解决什么问题CSV最大的用处是在不同系统之间传递表格数据。举个实际例子之前我们团队需要把数据库里两千多万条用户数据导出给数据部门做分析。用Excel文件太大了打不开。用数据库直连网络安全策略不允许。最后方案就是导出成CSV十几GB的文本文件用gzip压缩一下扔给数据部门。另一个常见场景是数据迁移。从旧系统导出CSV脚本处理一下再导入新系统。这种事我干过不下二十次每次都能发现CSV的一些小坑。还有一个容易被忽视的点CSV可以用来做配置。有些项目把配置写成CSV而不是JSON或YAML方便产品经理或运营人员直接编辑。怎么用起来Python自带csv模块不用额外安装。用法很简单但有几个地方新手容易踩坑。读取CSV文件的基本写法importcsvwithopen(data.csv,r,encodingutf-8)asf:readercsv.reader(f)forrowinreader:print(row)这段代码会把每一行数据变成一个列表。csv.reader返回的是一个迭代器不会一次性把整个文件读进内存这点在处理大文件时很关键。写入稍微有点区别withopen(output.csv,w,newline,encodingutf-8-sig)asf:writercsv.writer(f)writer.writerow([姓名,年龄,城市])writer.writerow([张三,28,北京])注意newline这个参数。不加的话Windows系统下会多出空行因为csv模块自己处理换行和文件系统的换行控制冲突了。还有编码问题。UTF-8可以跨平台但如果要在Excel里打开用utf-8-sig编码更好——带BOM的UTF-8Excel才能正确识别。字典形式的读写也很实用withopen(data.csv,r)asf:readercsv.DictReader(f)forrowinreader:print(row[姓名],row[年龄])withopen(output.csv,w,newline)asf:fieldnames[姓名,年龄,城市]writercsv.DictWriter(f,fieldnamesfieldnames)writer.writeheader()writer.writerow({姓名:张三,年龄:28,城市:北京})一些实际经验处理大文件时用csv.reader而不是手动按行读取加split(,)。这不仅仅是习惯问题csv.reader能正确处理带引号的字段自己写split处理不了张三,李四这样的字段——逗号在引号内不应该被当成分隔符。分隔符问题经常遇到。有些人用tab分隔有些系统用分号。可以指定delimiter参数readercsv.reader(f,delimiter\t)有一种情况坑了我很久——空行中的空字段。CSV规范里一行数据末尾的空字段可以省略也可以留空。不同的CSV生成器的处理方式不一样。对于关键字段读进来后最好检查一下是不是None或空字符串。另一个问题日期格式。不同系统输出的日期格式差别很大2024-01-15和01/15/2024并存的情况很常见。统一转换成标准格式再处理是个好习惯。处理坏数据也很重要。一个文件里可能有十万行是好的就一行有问题。用try...except捕获异常把问题行记录下来然后跳过比程序直接崩溃要实用得多。之前处理一次对账数据就因为一行有奇怪的编码字符程序跑了五个小时突然挂了整个人都不好了。和其他格式的比较CSV、JSON、Excel、Parquet这些格式各有适用场景。CSV vs JSONCSV更节省空间尤其数据量大时。JSON的好处是能表示嵌套结构CSV只能存平面表格。如果你的数据有复杂的层级关系比如用户信息和订单列表用JSON更合适。如果就是一张简简单单的表格CSV更轻量。CSV vs Excel文件主要区别是CSV只有数据不保存格式、公式、多sheet这些信息。有些同事喜欢用Excel保存数据然后发现文件打不开了——Excel的二进制格式容易损坏。CSV是纯文本几乎不可能损坏。但Excel能存多张表、能设置单元格颜色、能写公式这些CSV做不到。如果需要这些功能可以考虑用openpyxl库处理Excel文件。CSV vs ParquetParquet是列式存储格式压缩率高读取速度快尤其适合做数据分析。体积能比CSV小好几倍读取部分数据时不需要读整个文件。但Parquet的兼容性不如CSV很多工具不支持直接打开。日常开发中小规模数据直接用CSV大数据量分析场景才考虑Parquet。CSV vs SQLite这个对比有点意思。SQLite是一个完整的数据库引擎支持SQL查询、索引、事务。CSV只是一个简单的数据格式。但如果数据量不大又需要做查询用SQLite比CSV更方便。反过来如果只是简单的数据交换SQLite又显得重了。看场景说话。实际项目里我也见过混用的方案。先用CSV把数据快速导出来用Python脚本清洗转换最后导入数据库中。这样既利用了CSV的简单通用又借助Python的能力做复杂处理。一个工具解决不了所有问题组合才是常态。