python
内置的csv
模块可以帮助我们操作csv
文件
一、什么是csv
文件
csv
的全称是Comma-Separated Values
,意思是逗号分隔值,通俗点说就是一组用逗号分隔的数据。CSV
文件可以用excel
打开,会显示如下图所示:
这个文件用文本
打开显示是这样的,这是它原始的样子:
二、读文件
1. 使用reader
reader
接收一个可迭代的对象(比如csv文件),能返回一个生成器,就可以从其中解析出csv
的内容:比如下面的代码可以读取csv的全部内容,以行为单位:
import csv
path = '/Users/wuyaa/Desktop/test.csv'
with open(path, 'r') as f:
reader = csv.reader(f)
for row in reader:
print(row)
可以得到如下所示结果:
['username', 'password', 'address']
['zhuyy', '123456', '杭州']
['lsu', '2084_73', '北京']
['lkd', '63*$er', '天津']
['dfj', '09rjs65', '重庆']
['dkg', 'dhj634', '上海']
可以看出,csv
模块帮我们把每一行按照逗号
分隔成一个数组,这样我们在使用具体值:
for row in reader:
address = row[2]
使用上述的reader
可以实现csv
的读取,但是它是硬编码。例如下一次我们的csv
文件列顺序有所改变:
username,address,password
zhuyy,杭州,123456
lsu,北京,2084_73
lkd,上海,63*$er
dfj,深圳,09rjs65
dkg,广州,dhj634
这样我们就还需要去修改源码,对于这种情况推荐使用DictReader
2. 使用DictReader
import csv
path = '/Users/wuyaa/Desktop/test.csv'
with open(path, 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f)
for row in reader:
print(row)
结果:
OrderedDict([('username', 'zhuyy'), ('address', '杭州'), ('password', '123456')])
OrderedDict([('username', 'lsu'), ('address', '北京'), ('password', '2084_73')])
OrderedDict([('username', 'lkd'), ('address', '上海'), ('password', '63*$er')])
OrderedDict([('username', 'dfj'), ('address', '深圳'), ('password', '09rjs65')])
OrderedDict([('username', 'dkg'), ('address', '广州'), ('password', 'dhj634')])
可以看出csv
将每一行自动转换成有序字典,我们可以对字典get
取值。
OrderedDict
的参数:
-
fieldnames
指定返回字典的字段名
,如果没有指定,则将第一行作为字段名[我们上面就是默认第一行作为字段名
],如果指定了字段名,则第一行将作为内容返回
reader = csv.DictReader(f, fieldnames=['name', 'addr', 'pw'])
则结果为
OrderedDict([('name', 'username'), ('addr', 'address'), ('pw', 'password')])
OrderedDict([('name', 'zhuyy'), ('addr', '杭州'), ('pw', '123456')])
OrderedDict([('name', 'lsu'), ('addr', '北京'), ('pw', '2084_73')])
OrderedDict([('name', 'lkd'), ('addr', '上海'), ('pw', '63*$er')])
OrderedDict([('name', 'dfj'), ('addr', '深圳'), ('pw', '09rjs65')])
OrderedDict([('name', 'dkg'), ('addr', '广州'), ('pw', 'dhj634')])
-
restkey
填充缺少的字段名
-
restkey
填充缺少的字段内容
如以下:
zhuyy,杭州,123456,11
lsu,北京,2084_73,22
lkd,上海,63*$er,33
dfj,深圳,09rjs65,44
dkg,广州
import csv
path = '/Users/wuyaa/Desktop/test.csv'
with open(path, 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f, restkey='缺少的名称', restval='缺少的内容')
for row in reader:
print(row)
结果:
OrderedDict([('username', 'zhuyy'), ('address', '杭州'), ('password', '123456'), ('缺少的名称', ['11'])])
OrderedDict([('username', 'lsu'), ('address', '北京'), ('password', '2084_73'), ('缺少的名称', ['22'])])
OrderedDict([('username', 'lkd'), ('address', '上海'), ('password', '63*$er'), ('缺少的名称', ['33'])])
OrderedDict([('username', 'dfj'), ('address', '深圳'), ('password', '09rjs65'), ('缺少的名称', ['44'])])
OrderedDict([('username', 'dkg'), ('address', '广州'), ('password', '缺少的内容')])
二、写文件
1.使用writer
import csv
with open('test2.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['Spam'] * 5 + ['Baked Beans'])
writer.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
使用writer.writerow
写入字符串列表。
2.使用DictReader
import csv
with open('names.csv', 'w') as csvfile:
# 设置表头
fieldnames = ['first_name', 'last_name']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})
writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})
使用DictReader
的writerow
可以写入字典,这种使用场景更加的广泛,从数据库中取数据,然后将数据序列化成字典
,再将字典写入csv
是比较通用的做法。
例如在django
中
# models.py
from django.db import models
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
address = models.CharField(max_length=64)
# views.py
from django.views import View
from django.forms import model_to_dict
import csv
class UserView(View):
def get(self, request):
pass
def save_csv(self, request):
with open('users.csv', 'w') as csvfile:
# 设置表头
fieldnames = ['username', 'password', 'address']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader() # 写入表头
# 从 request 中获取查询结果集
queryset = self.get_queryset(request)
for user in queryset:
data = model_to_dict(user)
writer.writerow(data)