如何用Python的DictWriter正确生成CSV?解决写入覆盖行问题
解决CSV写入时覆盖行的问题
兄弟,你的代码之所以每次都会覆盖之前的内容,主要是这俩核心问题:
- 每次调用
samp函数都用wb模式打开文件,这会直接清空原有文件的内容,而不是追加新行; - 全局的
onlyKeys每次调用都追加字段,而且每次打开文件都重新写header,相当于每次都从头开始重建文件,之前的内容自然就没了。
给你两种实用的解决方案,根据你的场景选就行:
方案一:先收集所有数据,一次性写入(推荐)
如果你的数据可以提前收集完再写入,这种方式最省心,也避免了多次操作文件的开销:
import csv # 先初始化存储数据的列表和字段名 data_records = [] onlyKeys = ['date'] def samp(date, field): onlyKeys.append(field) # 把每条数据存到列表里暂存 data_records.append({'date': date, field: 1}) # 添加你的数据 samp('jan 10 2018 23:34:55','Video Error1') samp('jan 10 2018 23:34:56','Video Error2') # 还可以继续添加更多数据... # 一次性写入CSV文件 with open('fulltest.csv', 'w', newline='') as myFile: # Python3用newline=''避免空行;Python2换成'wb' writer1 = csv.DictWriter(myFile, fieldnames=onlyKeys) writer1.writeheader() # 只写一次header就够了 writer1.writerows(data_records) # 批量写入所有暂存的数据 print('所有数据都写完啦')
方案二:动态追加行(适合实时产生数据的场景)
如果数据是实时过来的,没办法提前收集完,那就得用追加模式打开文件,还要判断文件是否存在来决定要不要写header,同时保证每行的字段都完整:
import csv import os onlyKeys = ['date'] def samp(date, field): onlyKeys.append(field) # 检查文件是否已经存在 file_exists = os.path.isfile('fulltest.csv') # 用追加模式打开文件:Python3用'a',Python2换成'ab' with open('fulltest.csv', 'a', newline='') as myFile: writer1 = csv.DictWriter(myFile, fieldnames=onlyKeys) # 只有文件是第一次创建时才写header if not file_exists: writer1.writeheader() # 构造完整的行数据,没有值的字段填空字符串,避免字段缺失 row_data = {'date': date, field: 1} for key in onlyKeys: if key not in row_data: row_data[key] = '' writer1.writerow(row_data) print('这条数据已经追加进去啦') samp('jan 10 2018 23:34:55','Video Error1') samp('jan 10 2018 23:34:56','Video Error2')
小提醒
Python2和Python3打开CSV文件的模式有差异:Python2用wb/ab,Python3用w/a加上newline='',这样能避免每行之间多出空行。
内容的提问来源于stack exchange,提问作者Breme Arunprasath
相关产品推荐
相关产品推荐

