【python教程】6、文件
1、打开文件
open 函数,位于自动导入的模块 io 中,返回一个文件对象。
>>>f = open('somefile.txt')
'''
1、open的参数 mode默认值为:rt(将文件视为经过编码的Unicode文本,因此将自动执行解码和编码,默认使用UTF-8编码,还将自动转换换行字符)
2、默认情况下,行以'\n'结尾。读取时将自动替换其他行尾字符('\r'或'\r\n');写入时将'\n'替换为系统的默认行尾字符
3、指定其他编码和Unicode错误处理策略,使用关键字参数:encoding和errors
4、mode(文件模式)最常见的取值:
'r':读取模式(默认值)
'w':写入模式,文件不存在时创建;打开文件时,既有内容将被删除(截断),并从文件开头开始写入
'x':独占写入模式,在文件已存在时引发FileExistsError异常
'a':附加模式,在既有文件末尾继续写入
'b':二进制模式(与其他模式结合使用,会关闭Unicode编码和换行符替换)
't':文本模式(默认值,与其他模式结合使用)
'+':读写模式(可与其他任何模式结合,表示可读可写)。'r+'和'w+'的重要差别:后者会截断文件。
5、通常,python使用‘通用换行模式’。在这种模式下,readlines等方法能够识别所有合法的换行符('\n'、\r'和'\r\n')。
若要使用这种模式,同时禁止自动转换,可设置关键字参数newline='';
若要只指定'\r'为合法的行尾字符,设置参数newline='\r'即可(这样读取时不会对行尾字符进行转换,但写入时会把'\n'替换为指定的行尾字符)。
6、若文件包含非文本的二进制数据,如声音剪辑片段或图像,你肯定不希望执行上述的自动转行,执行使用二进制模式(rb)来禁用与文本相关的功能。
'''
2、文件的基本方法
类似于文件的对象(有时称为:流)支持文件对象的一些方法,如支持read或weite,或两者都支持。urlopen返回的对象就是典型的 类似于文件的对象,它支持read和readline,但不支持write和isatty。
模块sys中的三个标准流(这些流都是 类似于文件的对象):
- 标准数据输入源:sys.stdin
- 提供给print的文本和向input提供的提示信息会出现在 sys.stdout 中,写入到sys.stdout的数据通常出现在屏幕上
- 错误消息(如栈跟踪)被写入到sys.stderr
1、文件的读取和写入:f.read 和 f.write(f:类似于文件的对象)
2、使用管道重定向输出:$ cat somefile.txt | python somescript.py | sort
- cat somefile.txt:将文件中的内容写入到标准输出 sys.stdout;
- 管道字符(|):将一个命令的标准输出链接到下一个命令的标准输入
- somescript.py中内容如下:
import sys
text = sys.stdin.read()
words = text.split()
print('wordcount', len(words))
3、随机存取:
此节中,将文件视为流,只能按顺序从头到尾读取。实际上,可在文件中移动,只访问感兴趣的部分(称为随机读取)。可使用文件对象的两个方法:seek和tell
seek(offset[, whence]):将当前位置(执行读取和写入的位置)移到offset和whence指定的地方。
- offset:指定了字节(字符)数;
- whence:默认值为io.SEEK_SET(0),偏移量相对于文件开头的(偏移量不能为负数);还可设置为
io.SEEK_CUR(1)
,相对于当前位置进行移动,偏移量可为负;或io.SEEK_END(2)
,相对于文件末尾进行移动
# 1、方法seek()
f = open(r'c:\data.txt', 'w')
f.write('0123456789')
f.seek(2)
f.write('world')
f.close()
f = open(r'c:\data.txt')
f.read() # 结果为:'01world789'
# 2、方法tell():返回当前位于文件的什么位置
>>> f = open(r'c:\data.txt')
>>> f.read(2) # '01'
>>> f.read(1) # 'w'
>>> f.tell() # 3
4、读取和写入行
readline:可不提供任何参数,读取一行(从当前位置到下一个分行符的文本);也可提供一个非负整数,指定读取多少个字符。
readlines:读取文件中的所有行,并以列表的方式放回
writelines:接受一个字符串列表(可以是任何序列或可迭代对象),并将这些字符串写入到文件(或流)中。注意:写入时不会添加换行符,须自行添加;另外,没有方法writeline,可使用write。
5、关闭文件
通常,程序退出时将自动关闭文件对象(也可能在退出程序前)。关闭文件,在有些操作系统和设置中,可避免无意义地锁定文件以防修改;还可避免用完系统可能指定的文件打开配额。
对于写入过的文件,一定要将其关闭,因为python可能会缓冲你写入的数据,如果程序因某种原因崩溃,数据可能不会写入到文件中。
若要重置缓冲,让修改反映到磁盘文件中,但又不想关闭文件,可使用方法flush。但根据使用的操作系统和设置,flush可能处于锁定考虑而禁止其他正在运行的程序访问这个文件。
确保文件得以关闭:
# 1、使用try/finally语句
# 在这里打开文件
try:
# 将数据写入到文件中
finally:
file.close()
# 2、使用with语句:到达语句末尾时,将自动关闭文件,即便出现异常亦如此。with实际上是个非常通用的结构,允许你使用所谓的上下文管理器。
with open('file.txt') as f:
do_something(f)
6、上下文管理器:是支持两个方法的对象,__enter__
和__exit__
。
__enter__
:不接受任何参数,在进入with语句时被调用,其返回只被赋给关键字as后面的变量。
__exit__
:接受三个参数:异常类型、异常对象和异常跟踪。在离开方法时调用。若返回False,将抑制所有的异常。
文件也可用作上下文管理器。__enter__
返回文件对象本身,__exit__
关闭文件
3、迭代文件内容
1、每次迭代一个字符(或字节)
# 1、使用read遍历字符
with open('file.txt') as f:
char = f.read(1)
where char: # 到达文件末尾时,将返回一个空字符串
print('processing:', char)
char = f.read(1) # 此语句重复,通常被视为坏事
# 2、使用read遍历字符--优化(胜过例1,避免了重复代码)
with open('file.txt') as f:
where Ture:
char = f.read(1)
if not char:
break # 过多的使用break,会导致代码更难理解,但这里避免了重复代码
print('processing:', char) # 这里与上面的示例重复,可写一个方法
2、每次迭代一行,使用readline遍历
with open('file.txt') as f:
where True:
line = f.readline()
if not line:
break
print('processing:', line)
3、读取所有内容(文件不大时)
# 1、使用read迭代所有字符(方法read将整个文件读取到一个字符串中)
with open('file.txt') as f:
for char in f.read():
print('processing:', char)
# 2、使用readline迭代行
with open('file.txt') as f:
for line in f.readlines():
print('processing:', line)
4、使用fileinput实现延迟行迭代(延迟:只读取实际需要的文本部分)
# 迭代大型文件的行时,用readlines会占用很多内存,可结合使用while和readline,但在python中,在有可能时,应首选for循环
import fileinput # filename会打开文件
for line in fileinput.input(filename): # input帮助迭代多个输入流中的行
print('processing:', line)
5、文件迭代器(文件是可迭代的,可在for循环中使用文件来迭代行)(最常见的方法)
# 1、迭代文件,使用with确保文件得以关闭
with open(filename) as f:
for line in f:
print('processing:', line)
# 2、迭代文件:不将文件对象赋给变量(不写入文件时可这样操作),让python负责关闭文件
for line in open(filename):
print('processing:', line)
# 3、迭代sys.stdin(标准输入)
import sys
for line in sys.stdin:
print('processing:', line)
# 4、可对迭代做的事情基本都可对文件做
# 使用print来写入文件,将自动在提供的字符串后添加换行符
>>> f = open('file.txt', 'w')
>>> print('First', 'line', file=f)
>>> print('Second', 'line', file=f)
>>> f.close()
# 将行转换为字符串列表
>>>lines = list(open('file.txt'))
# 对打开的文件进行序列解包(不常见,因为不知道文件包含多少行)
first, second = open('file.txt') # 读取文件后并没有关闭,会有点粗糙,但并非致命