Python语法速查: 12. 文件与输入输出
Posted 初级电路与软件研究
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python语法速查: 12. 文件与输入输出相关的知识,希望对你有一定的参考价值。
本篇索引
(1)文件基本操作
(2)文件内容读出与文件迭代器
(3)输入与输出
(5)shutil模块
(6)os模块中的常用文件操作
(7)CSV文件操作
(1)文件基本操作
● 文件常用操作
内置函数或方法 | 描述 |
---|---|
open(name [,mode [,buffering]]) | 内置函数。用来打开文件,返回一个文件对象(file对象)。详见下述 |
f.close() | file对象方法,关闭文件。 |
f.read([n]) | file对象方法,读取最多n个字节,若不指定n,则默认读取整个文件。读出的内容以字符串形式返回。 |
f.readline(size=-1) | file对象方法。读取整行并返回一个字符串,若指定size,则本行最多读取size个字节。读出整行时返回字符串中含换行符。 |
f.readlines(hint=-1) | file对象方法。读取所有行并返回一个列表,每行的字符串为一个列表元素,hint为最多读取的行数。(由于现在可以直接对文件对象进行迭代,故readlines()这个方法现在不怎么用了,详见下面文件迭代器说明。) |
f.write(s) | file对象方法。将给定字符串s写入文件。(若要换行,需要自己在s中加Python换行符) |
f.writelines(lines) | file对象方法。写入序列lines中的所有字符串。(换行同上) |
f.tell() | file对象方法。返回本文件对象在文件中的当前位置指针,返回值为整数。 |
f.seek(offset [,whence]) | file对象方法。查找文件位置,详见下述 |
f.truncate(size=None) | file对象方法。将文件截短为最多size字节。 |
f.flush() | file对象方法。将输出缓冲区的内容强制写入磁盘并清空输出缓冲区。 |
f.fileno() | file对象方法。返回一个整数文件描述符。 |
f.isatty() | file对象方法。判断file对象是否为一个交互式终端,返回布尔值。 |
● file对象常用属性
属性 | 说明 |
---|---|
closed | 布尔值,表示文件是否已关闭。 |
mode | 字符串,文件的打开模式。详见下面open()函数的mode参数说明。 |
name | 字符串,文件名 |
newlines | 表示在文件中实际遇到的换行符表示,若还没遇到换行符,则为None。 |
encoding | 字符串,表示文件编码。详见下面open()函数的encoding参数说明。 |
● open(name ,mode=\'r\' ,buffering=-1, errors=None, newline=None, closefd=True, opener=None)
说明:
参数name:含完整路径的文件名
参数mode:见下表中的各个字符,可组合使用,如\'rb\'或\'rw\'等。
参数buffering:默认为-1,即缓冲区大小为本系统的磁盘块大小(常为4096字节),也可用其他大于1的数字指定缓冲区大小(字节数)。
参数encoding:文件的编码名称,如:\'utf-8\'、\'ascii\'、\'cp936\'等。
参数newline:控制通用换行符模式的行为,可设置为:\'\\n\', \'\\r\', \'\\r\\n\', \'\', None等。 如果设置为None,所有形式的换行符(如:\'\\n\', \'\\r\', \'\\r\\n\')都会被转换为\'\\n\'。 如果设置为\'\'(空字符串),则所有形式的换行都会被识别为换行符,但输入文本不会转换;
参数closefd:布尔值,控制在调用close()方法时,是否实际关闭底层的文件描述符,一般默认为True。
字符 | 含义 |
---|---|
r | 读模式(默认) |
w | 写模式(首先会把文件现有内容全部清除,然后从头开始写) |
x | 若文件已存在,使用x模式会报错 |
a | 追加写模式(从文件现有内容结尾处开始写) |
b | 二进制模式 |
t | 文本模式(默认) |
+ | 读/写模式,可以跟\'r\'或\'w\'组合使用。\'r+\'表示可读写(但不清除现有内容);\'w+\'表示可读写(先清除所有内容) |
关于“文本模式”和“二进制模式”的说明:
在Python3中,在文本模式下打开文件,读取操作将返回Unicode字符串;如果在二进制模式下打开文件,将返回字节字符串。
如果文件本身是二进制数据文件,由于read()方法的返回内容格式为字符串,故“文本模式”和“二进制模式”读取的内容看上去都像乱码,需要进一步的处理。
对于文本文件,用“文本模式”和“二进制模式”的效果差不多,唯一的不同是在“文本模式”下,Python会自动对文件中的换行符作一些转换。 在读取Windows格式的文本文件时,会将Windows形式的换行符\'\\r\\n\'转换成Python标准形式的换行符\'\\n\'。 同样的,在写入Windows文本文件时,会将Python的换行符\'\\n\'转换成Windows形式的\'\\r\\n\'写入文件。 在Linux平台不作任何转换。
● seek(offset [,whence])
说明:
根据给定的offset和whence中的偏移规则,将本文件对象的当前位置指针移动到任意位置。offset为一个整数,whence表明offset的偏移起始位置,见下表: (若使用宏名称,需要import os模块
宏名称 | 整数值 | 说明 |
---|---|---|
os.SEEK_SET | 0 | offset从文件头开始偏移。 |
os.SEEK_CUR | 1 | offset为从当前位置开始偏移。 |
os.SEEK_END | 2 | offset为从文件末尾开始偏移,此时offset通常为负数。 |
● 确保文件被正常关闭的方法
方法一:使用 try / finally
f = open(filename) # 打开文件 try: # …… 文件操作 finally: f.close()
方法二:使用 with 上下文管理器
with open(filename) as wf: # with 打开文件后将其赋值到变量 wf 上 do_somethin(wf) # 上面语句块结束后,文件被自动关闭,即使是异常引起的结束也是如此。
(2)文件内容读出与文件迭代器
如果文件不是很大,传统的文件读出的操作是像下面这样子的(不使用文件迭代器)。
将文件内容一次性全部读出,每次处理一个字符:
f = open(filename) for c in f.read(): print(c) f.close()
将文件所有的行一次性全部读出,每次处理一行:
f = open(filename) for line in f.readlines(): print(line) f.close()
若文件很大,则可以每次仅读取一行:
f = openfile(filename) while True: line = f.readline() if not line: break # 当line返回空值时,表面已读到文件尾 print(line) f.close()
而现在,文件对象本身是支持迭代的。也就是说,对于很大的文件,不用一次性全部读出所有内容,用文件对象迭代器就可以在每次循环时只读出文件的一部分。
文件迭代器的用法:
f = open(filename) for line in f: print(line) f.close()
也可以让Python自己负责关闭文件:
for line in open(filename): print(line)
● 使用fileinput模块
使用fileinput模块也可以对文件进行迭代,fileinput模块还提供一些其他方法使能够更方便地对多个文件和多个输入输出流操作。
● fileinput模块中的常用函数
函数 | 说明 |
---|---|
input(files=None, inplace=False, backup=\'\', mode=\'r\', openhook=None) | 新建一个FileInput类的实例,用于对若干文件进行操作。files参数为文件名或输入流列表,若缺省则默认为sys.argv[1:]。若inplace参数为True,文件将原地处理,即:将文件内容复制到backup指定的文件,并将标准输出流重定向到本文件。 |
filename() | 返回当前文件的名称。 |
fileno() | 返回当前打开文件的文件描述符(整数),若未打开文件,则返回-1。 |
lineno() | 返回当前累计的行数。即若处理多个文件,行数会累计。 |
filelineno() | 返回当前文件当前行行号。 |
isfirstline() | 刚才读入的行是否为文件的第一行。 |
isstdin() | 最后读入的一行是否来自sys.stdin |
nextfile() | 关闭当前文件,移动到下一个文件。 |
close() | 关闭序列。 |
用fileinput对文件进行迭代:
import fileinput for line in fileinput.input(filename): print(line)
对目标文件的每行后面添加行号注释:
# test.py import fileinput for line in fileinput.input(inplace=True): # files参数为空,默认使用sys.argv[1:]作为输入流列表 line = line.rstrip() num = fileinput.lineno() print(\'%-40s # %2i\' %(line, num)) # 运行:python test.py a.txt 后,会在a.txt文件的每一行后添加注释行号
(3)输入与输出
Python解释器提供了3种标准文件对象:标准输入、标准输出、标准错误,分别在sys模块中表示为:sys.stdin, sys.stdout, sys.stderr。 通常,stdin被映射到接受用户键盘输入信息,而stdout和stderr在屏幕上生成文本。在某些情况下,集成开发环境(IDE)可能会更改sys.stdin, sys.stdout和sys.stderr。
文件的read()和write()也可以用于输出流和输入流,效果与print()和input()内置函数相同。
import sys sys.stdout.write(\'Hello\') # 相当于:print(\'Hello\') a = sys.stdin.readline() # 相当于:a = input() ,使用stdin在a中会有一个换行符。
Linux中的管道符号(|),将前一个命令的“标准输入”和后一个命令的“标准输出”连在一起,如果你的程序要读取管道中来的数据,只需使用读标准输入即可,如:
import sys tx = sys.stdin.read()
● print()函数
print()函数可接收若干个要在屏幕上打印的参数,入参中间用逗号隔开,在屏幕上各个显示的入参之间以空格分隔。 若要将print()的内容重定向到一个文件,可以使用file=outfile关键字参数。若要更改默认的空格分隔,可使用sep=sepchar关键字参数。
print(\'Hello\', 1, 2, 3) # 输出显示为:Hello 1 2 3 print(\'Hello\', 1, 2, 3, sep=\',\') # 输出显示为:Hello,1,2,3 print(\'Hello\', 1, 2, 3, file=f) # 输出内容重定向到文件对象f
若要在输出文本中大量插入变量,可使用format()方法或string.Template方法,关于它们的用法 详见这里。
● 生成器输出
生成器函数可以以一个数据片段序列的形式输出I/O流,可以像 print() 或 write() 语句一样使用 yield 语句,例如:
def countdown(n): while n > 0: yield "n is %d\\n" % n n -= 1 yield "finish\\n" # 将上述输出发送到文件f: count = countdown(5) f.writelines(count) # 由writelines()负责迭代生成器 # 将上述输出重定向到套接字s: count = countdown(5) for chunk in count: s.sendall(chunk) # 由for循环负责迭代生成器 # 将所有输出捕获到一个字符串中 count = countdown(5) out = "".join(count) # 由join()负责迭代生成器
一个生成器可以输出小片段文本,另一个函数可以将这些片段收集到大型缓冲区中, 以实现较大的、更高效的I/O操作。对于将输出发送到文件或网络套接字的程序, 这种生成器方法可以显著减少内存的使用,因为整个输出流可以在较小的片段中生成和处理, 而不需要首先收集到一个大型字符串中。下面是一个使用例子:
def countdown(n): while n > 0: yield "n is %d\\n" % n n -= 1 yield "finish\\n" chunk_list = [] buffered_size = 0 for chunk in count: chunk_list.append(chunk) buffered_size += len(chunk) if buffered_size >= MAXBUFFERSIZE: outfile.write("".join(chunk_list)) # 将几次的生成器输出拼接成一个中等大小字符串,写入文件 chunks_list.clear() buffered_size = 0 outfile.write("".join(chunk_list)) # 这句用来将最后几次循环中还剩在chunk_list中的数据写入文件
(4)pickle与shelve模块
● pickle模块
pickle模块将对象序列化为一个字节流,这个字节流可以写入到文件并在以后从文件读出还原成对象。出于安全考虑,程序不应该处理来自不可信来源的文件来还原成对象。
序列化用户定义类的实例时,只会序列化数据,不会保存相应的类定义,序列化后的数据只包含相关类和模块的“名称”。且在还原一个实例时,不会调用其类方法__init__()。
pickle模块比较适合用于序列化:数字、字符串、元组、列表、只包含可序列化对象的字典、在模块顶层定义的用户定义类的实例。
● pickle常用方法
函数 | 说明 |
---|---|
pickle.dump(obj, file, protocol=None) | 将obj序列化并存储到“文件对象”file中。protocol可为:0、1、2、3、pickle.HIGHEST_PROTOCOL(自动选择最新协议)。若obj不支持序列号,则引发pickle.PicklingError异常 |
pickle.dumps(>obj, protocol=None) | 与上面的dump()功能相同,只是不将序列化后的对象写入文件,而是将其作为一个bytes对象返回。 |
pickle.load(file) | 从“文件对象”file中加载并还原一个序列化对象。如果该文件无法还原,则引发pickle.UnpicklingError异常;如果检测到文件尾,则引发EOFError异常。 |
pickle.loads(bytes_obj) | 与上面load()功能相同,但不是从文件对象还原对象,而是从入参的bytes对象还原。 |
序列化对象和还原序列化示例:
# 序列化写入文件: obj1 = SomeObject() obj2 = SomeObject() f = open(filename, \'wb\') pickle.dump(obj1, f) # 先写入obj1 pickle.dump(obj2, f) # 再写入obj2 f.close() # 还原序列化对象: f = open(filename, \'rb\') o1 = pickle.load(f) o2 = pickle.load(f) f.close()
● shelve模块
shelve模块是基于pickle模块建立的,但比pickle模块更加自动化。模块中的open()函数会创建一个Shelve对象,可以当做一个普通字典来使用(键名必须是字符串)。 但与字典不同的是,它包含多所有对象都是通过基于散列表的数据库(dbhash、dbm或gdbm)存储在磁盘上。 在调用其sync()或close()方法后,其内容将被自动写入文件。
shelve模块使用anydbm模块来选择合适的DBM模块使用。在大多数标准Python安装中,它有可能是基于Berkeley库的dbhash。
shelve.open()函数语法如下:
open(filename [,flag=\'c\' [,protocol [,writeback]]])
open()函数打开一个shelve文件,如果文件不存在,就创建它,filename应该是数据库文件名并且不应该包含后缀。
flag可为\'r\', \'w\', \'c\', \'n\'。\'r\'表示只读访问;\'w\'表示读写访问;\'c\'表示如果数据库不存在便生成数据库文件; \'n\'表示强制生成新的数据文件。
protocol含义同pickle模块。writeback为缓存行为,若为True,则所有被访问的条目都缓存在内存中,仅当shelve关闭后才写回, 默认值是False。
● shelve支持的字典操作
操作 | 说明 |
---|---|
d[key] = data | 将数据存储在键key上 |
data = d[key] | 在健key上读出数据 |
del d[key] | 删除键key及其数据 |
d.has_key(key) | 测试键key是否存在 |
d.keys() | 返回所有键名 |
d.close() | 关闭shelve |
d.sync() | 将未保存的数据写入磁盘 |
shelve使用示例:
import shelve # 保存到文件: s = shelve.open(\'test\') # shelve模块会自动添加扩展名.dat s[\'a\'] = [1,2,3] s.close() # 保存内容到文件 # 从文件中读出: s = shelve.open(\'test\') print(s[\'a\']) s[\'b\'] = \'abc\' # 追加内容 del s[\'a\'] # 删除键\'a\'及其内容 s.sync() # 强制保存内容到文件 s.close() # close()会自动调用sync()方法而实现保存作用。
shelve还可以不生成文件而将其数据放在内存中的某个字典上,下面的Shelf返回一个shelve对象, 但是其底层存储不是在文件上,而是放在入参dict的字典中:
Shelf(dict [,protocol [,writeback]])
(5)shutil模块
shutil模块用于执行高级的普通文件操作,例如:复制、移动、重命名等,但并不能处理管道、块设备等特殊文件。
函数 | 说明 |
---|---|
shutil.copy(src, dst) | 将文件src复制到文件或目录下(若dst为目录,则复制到目录下;若dst为一文件名,则复制到dst同级目录下并重命名为指定文件名)。返回新复制的文件名(含路径) |
shutil.copy2(src, dst) | 与上面的copy()类似,但同时复制了最后访问时间和修改时间。 |
shutil.copytree(src, dst, symlinks=False, ignore=None) | 递归地复制src下的整个目录树,创建目标目录dst(且不应该已存在),并使用copy2()复制每个文件。如果symlinks为True,则对于源目录树中的链接文件仅作为链接文件复制,否则复制真实文件到新目录树。 如果在复制过程中发生错误,则将收集错误,处理结束时提示Error异常,异常的参数是一份包含了所有错误的元组列表 (srcname, dstname, exception)。 |
shutil.move(src, dst) | 将文件或目录从src移动到dst。如果src移动到了不同的文件系统中,将递归地复制src。 |
shutil.rmtree(path, ignore_errors=False, onerror=None) | 删除整个目录树。如果ignore_errors为真,错误将被忽略;否则错误由onerror函数处理。 |
shutil.copymode(src, dst) | 将文件的模式权限位(如:777)从src复制到dst |
shutil.copystat(src, dst) | 将权限位、最后访问时间、最后修改时间从src复制到dst。文件内容、拥有人等保持不变。 |
shutil.copyfile(src, dst) | 将src的内容全部读出后,复制到dst。 |
shutil.copyfileobj(f1, f2 [,length]) | 将打开的文件对象f1中的所有内容复制到打开的文件对象f2,length可指定最大缓冲容量,若位负数,则一次操作中复制全部数据。 |
shutil.ignore_pattern(*patterns) | 创建一个函数,忽略所有patterns中给出的通配符样式模式。返回函数的主要用途是作为shutil.copytree()函数的ignore参数,也可给os.walk()函数使用。 |
(6)os模块中的常用文件操作
● os模块
函数/属性 | 说明 |
---|---|
sep | 属性。操作系统用于分隔路径各个部分的字符,在Linux上为\'/\',在Windows上为\'\\\',在Mac上为\':\' |
getcwd() | 返回当前进程的工作路径字符串。 |
chdir(path) | 将当前进程的工作目录修改为path。 |
listdir(path) | 返回包含目录路径中各文件名和子目录名的列表(不包括\'.\'和\'..\'),不递归搜索。 |
mkdir(path [,mode]) | 创建模式为mode的目录,默认模式为777。 |
makedirs(path [,mode]) | 在创建目录时,会同时创建包含叶子目录所需要的中间级目录,若叶子目录已存在或者无法创建,将引发OSError异常。 |
rmdir(path) | 删除目录,目录必须为空。 |
removedirs(path) | 递归地目录删除函数,即在path描述链上的所有目录都将被删除。若其中某个目录不为空,则停止继续向上删除目录。 |
remove(path) | 删除文件,同unlink()函数。 |
unlink(path) | 删除文件,同remove()函数 |
rename(src, dst) | 将文件或目录src重命名为dst |
renames(old, new) | 它会尝试创建新路径所需的中间目录,重命名完成之后,将使用removedirs()删除旧名称的目录链。 |
● os.path模块
os.path模块以一种可移植的方式操作路径名称,可由os模块导入。
函数 | 说明 |
---|---|
文件与目录的路径操作 | |
exists(path) | 如果path指定的文件或目录存在,则返回True。若path是已损坏的符号链接,则返回False。 |
lexists(path) | 功能同上,但只要链接文件存在,即便链接损坏也返回True。 |
isdir(path) | 如果path是目录则返回True。 |
isfile(path) | 如果path是文件则返回True。 |
islink(path) | 如果path是符号链接则返回True。 |
ismount(path) | 如果path是挂载点则返回True。 |
文件与目录的属性操作 | |
getsize(path) | 返回path的大小,以字节为单位 |
getatime(path) | 返回最后一次访问path的时间,返回值是从纪元起始点开始的秒数。 |
getctime(path) | 返回创建path的时间(Windows)或最后一次修改path的时间(Linux),返回值是从纪元起始点开始的秒数。 |
getmtime(path) | 返回最后一次修改path的时间,返回值是从纪元起始点开始的秒数。 |
samefile(path1, path2) | 如果path1和path2引用同一个文件或目录,返回True。 |
sameopenfile(fp1, fp2) | 如果打开的文件对象fp1和fp2引用同一个文件,则返回True。 |
samestat(stat1, stat2) | 如果fstat()、lstat()或stat()饭hi的stat对象stat1和stat2引用同一个文件,则返回True。 |
以下为纯路径字符串操作(不管实际目录或文件是否存在) | |
dirname(path) | 返回path所在目录的名称。 |
basename(path) | 返回path的基本名称(即不含父目录及以上路径)。 |
abspath(path) | 返回path的绝对路径。 |
isabs(path) | 如果path是绝对路径名称,则返回True。 |
normpath(path) | 返回标准化路径名称。它将折叠多余分隔符,在Windows上,它把正斜杠转换为反斜杠。 |
normcase(path) | 返回标准化路径名称并转换大小写,在不区分大小写的文件系统上,它把路径全转为小写字母,在Windows上,它把正斜杠转换为反斜杠。 |
join(path1 [,path2 [, ...]]) | 将一个或多个路径组件智能连接为一个路径名称,例如:join(\'home\', \'a\', \'b\')返回为 \'/home/a/b\' |
split(path) | 将path拆分为 (head, tail) 元组,tail为路径基本名称,head是tail之前的内容。相当于 (dirname(), basename())。 |
splitdrive(path) | 将path拆分为 (driver, filename) 元组。在Windows上,drive是驱动器名,在Linux上,drive为空字符串。 |
splitext(path) | 将path拆分为主文件名和后缀(扩展名),如 splittext(\'a.txt\') 的返回值为 (\'a\', \'.txt\') |
realpath(path) | 返回path的真实路径,并除去路径中的所有符号链接(Linux) |
relpath(path [,start]) | 返回从当前工作目录到path的一条相对路径,可以提供start参数来指定另一个起始目录。 |
commonpath(list) | 返回list中各个元素前缀路径相同的部分,如:os.path.commonpath([\'/usr/lib\', \'/usr/local/lib\']),返回:\'/usr\' |
commonprefix(list) | 返回list中各个元素前缀相同的部分,如:os.path.commonpath([\'/usr/lib\', \'/usr/local/lib\']),返回:\'/usr/l\' |
expanduser(path) | 将path中的用户主目录\'~\'替换成当前用户主目录的绝对路径名称。 |
expandvars(path) | 将path中的\'$name\'或\'${name}\'替换成相应环境变量中的值。 |
其他 | |
supports_unicode_filenames | 变量,如果文件系统支持Unicode文件名,那么此变量为True。(一般Windows为True,Linux为False) |
(7)CSV文件操作
csv模块用于读取和写入CSV文件,CSV文件由文本行组成,每一行都由分隔符分隔的值组成,分隔符通常是逗号(,)或制表符。
● 读取CSV文件
reader(csvfile [,dialect [,**fmtparms]])
reader()函数返回reader对象,生成输入文件csvfile中每一行输入的值。其中csvfile可以是任何可迭代的对象(一般可以是一个已打开的csv文件对象), 只要每次迭代生成一个完整的文本行即可。返回的reader对象也是一个迭代器,每次迭代生成一个字符串序列, 序列中的每个元素即为当前迭代行的每个被分隔内容的字符串。dialect参数既可以是包含某中某种方言名称的字符串, 也可以是Dialect对象。目前该模块仅支持两个内置方言:\'execl\'(默认值)、\'execl-tab\',但用户可定义其他方言。
在Linux主机上仅认utf-8格式编码的CSV文件,Windows主机上仅认gbk编码的CSV文件。
fmtparams是一个关键字参数集合,详见下表:
关键字参数 | 描述 |
---|---|
delimiter | 用来分隔的字符(默认为\',\') |
doublequote | 布尔标志,字段中遇见双引号的处理方式。若为True(默认值),则使用双引号;若为False,则在引号前添加转义字符(escapechar) |
escapechar | 转义字符,默认为None |
lineterminator | 行终止符(默认为\'\\r\\n\') |
quotechar | 用来引用包含分隔符的字符串(默认为双引号) |
skipinitialspace | 若为True,则忽略紧跟分隔符后的空格(默认为False) |
● 写CSV文件
writer(csvfile [,dialect [,**fmtparms]])
writer()函数返回可以用来创建CSV文件的写入对象,csvfile可以是支持write()方法的类文件对象。 dialect含义同reader();fmtparam含义也基本同reader(),但多了一个关键字参数可用:
关键字参数 | 描述 |
---|---|
quoting | 控制输出数据的引号添加行为,有4种设置:QUOTE_ALL(给所有字段添加引号)、QUOTE_MINIMAL(只给包含分隔符或以引号开头的字段添加引号)、 QUOTE_NONNUMERIC(给所有数字字段添加引号)、QUOTE_NONE(不给任何字段添加引号)。默认值为QUOTE_MINIAL |
writer()返回的对象支持以下方法:
方法 | 描述 |
---|---|
w.writerow(row) | 讲一个数据行写入文件,row必须是字符串序列或数字序列 |
w.writerows(rows) | 写入多行数据,rows必须是符合传递给writerow()方法的行的序列 |
● 字典式写入与读取CSV文件
DictReader(csvfile [,filednames [,restkey [,restval [,dialect [, **fmtparams]]]]])
返回可以像普通reader对象一样操作的对象,不同之处在于:读取文件迭代每一行时返回的是字典对象而不是字符串列表。 filednames指定在返回字典中用作键的字段名称,若忽略该参数则默认使用输入文件的第一行作为每列数据的键名称。 restkey提供用来存储超额数据的字典键名称(例如每行的数据比数据字段名称多时);restval指定输入中缺少值的字段的默认值。 restkey和restval的默认值为None。dialect和fmtparams的含义同reader()函数。
DictWriter(csvfile [,filednames [,restval [,extrasaction [,dialect [, **fmtparams]]]]])
返回可以像普通writer对象一样操作的对象,不同之处在于:可以将字典写入输出行。fieldnames指定写入文件的键名和键名顺序。 如果字典中缺少fieldnames指定的某个字段名称,那么写入restval的值。extrasaction是一个字符串,指定写入字典中的键未在fieldnames中列出时该如何做。 extrasaction中的默认值是\'raise\',即引起ValueError异常,可以使用值\'ignore\'来忽略异常。dialect和fmtparams的含义同writer()函数。
DictWriter的实例使用的方法同样也是:w.writerow(row) 和 w.writerows(rows) 方法。
以上是关于Python语法速查: 12. 文件与输入输出的主要内容,如果未能解决你的问题,请参考以下文章