Python——文件

一.打开文件

打开文件使用函数open,它位于自动导入的模块io中。函数open将文件名作为唯一必不可少的参数,并返回一个文件对象。

1.文件模式

若要通过写入文本来创建文件,光调用函数open是不能满足需求的,这时可以使用函数open的第二个参数。
函数open的参数mode的最常见取值:

写入模式让你能够写入文件,并在文件不存在时创建它。独占写入模式在文件已存在时会引发FileExietsError异常。在写入模式下打开文件会把已有内容删除(截断),并在文件开头开始写入。若要在已有内容末尾继续写入,需要使用附加模式。
‘+’ 表示即可读取也可写入;'r+‘和’w+’ 之间有个重要区别:前者不会 截断文件,后者 截断文件。
默认模式为’rt’,这表示将文件视为经过编码的Unicode文本,将自动执行解码、编码。且默认使用UTF-8编码。指定其它编码和Unicode错误处理策略,可使用关键字参数encoding和errors。这也可以自动转化为换行字符。默认情况下,行以’\n’结尾。读取时将自动替换其他行尾字符;写入时将’\n’替换为系统的默认行尾字符(os.linesep)。
通常,Python使用通用换行模式。在这种模式下,readlines等方法能够识别所有合法的换行符(‘\n’、‘\r’、‘\r\n‘)。若要使用这种模式,同时禁止自动转换,可以讲关键字参数newline设置为空字符串,如open(name,newline=’ ‘)。若要指定只将’\r’或’\r\n‘视为合法的行尾字符,可将参数newline设置为相应的行尾字符。读取时不会对行尾字符进行转换,但写入时将把’\n’替换为指定的行尾字符。
若文件包含非文本的二进制数据,可以使用二进制模式(如‘rb’)来禁用与文本相关的功能。
有几个更为高级的可选参数,用于控制缓冲以及更直接地处理文件描述符。要想获取这些参数的详细信息,可以参阅Python文档或在交互式解释器中运行help(open)。

二.文件的基本方法

:类似于文件的对象,支持read或write或者两者都支持。
标准流
标准数据输入源——sys.stdin;当程序从标准输入读取时,可以通过输入来提供文本,也可使用管道将标准输入关联到其他程序的标准输出。

1.读取和写入

文件最重要的功能是提供和接收数据。若有一个名为f的类似于文件的对象,可使用f.write来写入数据,还可以使用f.read来读取数据。与Python的大多数功能一样,在那些东西可用作数据方面,存在一定的灵活性,但在文本和二进制模式下,基本上分别将str和bytes类用作数据。
当调用f.write(string)时,你提供的字符串都将写入到文件中既有内容的后面。

>>>f=open('somefile.txt','w')
>>>f.write('hello,')
6
>>>f.write('World!')        
6
>>>f.close()

在使用完文件后,调用了方法close,后面将会详细介绍。
读取非常简单,只需要流告诉你要读取多少个字符(在二进制模式下是多少字节),如下列所示:

>>>f=open('somefile.txt','r')
>>>f.read(4)
'Hell'
>>>f.read()
'o, World!'

首先指定要读取多少个字符,接下来读取了文件中余下的全部内容(不指定读取多少个字符)。请注意,调用open时,可不指定模式,因为其默认值就是‘r’。

2.使用管道重定向输出

在bash等shell中,可依次输入多个命令,并使用管道将它们链接起来,如下:

$ cat somefile.txt | python somescript.py | sort

这条管道包含三个命令:
❶cat somefile.txt:将文件somefile.txt的内容写入到标准输出(sys.stdout)
❷ python somescript.py:执行Python脚本somescript。这个脚本从标准输入中读取,并将结果写入到标准输出。
❸sort:读取标准输入(sys.stdin)中的所有文本,将各行按字母顺序排序,并将结果写入到标准输出。
管道将一个命令的标准输出链接到下一个命令的标准输入。所以可以认为somescript.py从其sys.stdin中读取数据(这些数据是somefile.txt写入的),并将结果写入到sys.stdout(sort将从这里获取数据)

# somescript.py
#一个使用了sys.stdin的简单脚本
import sys
text=sys.stdin.read()
words=text.split()
wordcount=len(words)
print('Wordcount:',wordcount)
                               随机存取

这里将文件都视为流,只能按顺序从头到尾读取。实际上,可在文件中移动,只访问感兴趣的部分(称为随机存取)。这可以使用文件对像的两个方法:seek和tell。
方法seek(offset[,whence])将当前位置(执行读取或写入的位置)移到offset和whence指定的地方。参数offset指定了字节(字符)数,而参数whence默认为io.SEEK_SET(0),这意味着偏移量是相对于文件开头的(偏移量不能为负数)。参数whence还可设置为io.SEEK_CUR(1)或io.SEEK_END(2),其中前者表示相对于当前位置进行移动(偏移量可以为负),而后者表示相对于文件末尾进行移动。
示例:

>>>f=open(r'C:\text\somefile.txt','w')
>>>f.write('01234567890123456789')
20
>>>f.seek(5)
5
>>>f.write('Hello,LiMing')
12
>>>f.close()
>>>f=open(r'C:\text\somefile.txt')
>>>f.read()
'01234Hello,LiMing789'
#方法tell()返回当前在文件的位置
>>>f=open(r'C:\text\somefile.txt')
>>>f.read(3)
'012'
>>>f.read(2)
'34'
>>>f.tell()
5
3.读取和写入行,关闭文件

上述都是不太实用的方法,正常情况下都是使用方法readline进行整行的读取。调用这个方法时,可不提供任何参数(这是将读取一行并返回它);也可以提供一个正整数指定readline最多可读取多少个字符。所以,如果some_file.readline()返回的是‘Hello, liming!\n’,那么some_file.readline(5)返回‘Hello’。要读取文件的所有行,可使用方法readlines
方法writelines和readlines相反:接受一个字符串列表(实际上可以是任何序列或可迭代对象),并将这些字符串都写入文件(或流)中。这时请注意,在写入时不会添加换行符,所以必须自行添加。没有方法writeline,因为可以使用write
关闭文件要调用方法close。
通常情况下,程序退出时将自动关闭文件对象。然而,在有些操作系统和设置中,可以避免无意义的锁定文件以防修改。另外,这么做还可以避免用完系统可能指定的文件打开配额。
对于写入过的文件,一定要将其关闭,因为Python可能缓冲你写入的数据(将数据暂时存储在某个地方,以提高效率)。如果程序因为某种原因崩溃,数据可能根本不会写入到文件中。最好的做法是使用完文件后就将其关闭。
若要重置缓冲,使其所做的修改反映到磁盘文件中,但又不想关闭文件,可使用方法flush。但请注意,根据使用的操作系统和设置,flush可能出于锁定考虑而禁止其他正在运行的程序访问这个文件。
要确保文件关闭,可以使用一条try/finally语句,并在finally语句中调用close。

#在这里打开文件
try:
	#将数据写入到文件中
finally:
	file.close()

还有一条专门为此设计的with语句。

with open("somefile.txt") as somefile:
	 do_something(somefile)

with语句让你能够打开文件并将其赋给一个变量。到达该语句末尾时,即使出现异常,也会自动关闭文件。

				             上下文管理器

with语句是一个非常通用的结构,允许使用上下文管理器。上下文管理器是支持两个方法的对象:enter_和_exit.
方法_enter_不接受任何参数,在进入with语句时被调用,其返回值被赋给关键字参数as后的变量。
方法_exit_接受三个参数:异常类型、异常对象、异常跟踪。它在离开方法时被调用,若返回的是Flase,将抑制所有的异常。
文件也可用做上下文管理器,_enter_返回文件本身,_exit_关闭文件。

4.使用文件的基本方法

示例:

>>>f=open(r'C:\text\somefile.txt','w')
>>>f.write('Welcome to this file\n There is nothing here except\n This stupid haiku')
69
>>>f=open(r'C:\text\somefile.txt')
>>>f.read(7)
'Welcome'
>>>f.read(4)
' to '
>>>f.close()
>>>f=open(r'C:\text\somefile.txt')
>>>print(f.read())
Welcome to this file
 There is nothing here except
 This stupid haiku
>>>f.close()
>>>f=open(r'C:\text\somefile.txt')    #使用read()
>>>for i in range(3):				  #使用readline()
...    print(str(i) + ':' + f.readline(), end='') 
0:Welcome to this file
1: There is nothing here except
2: This stupid haiku
f.close()
>>>import pprint					#使用readlines()
>>>pprint.pprint(open(r'C:\text\somefile.txt').readlines())
['Welcome to this file\n',
 ' There is nothing here except\n',
 ' This stupid haiku']
>>>f=open(r'C:\text\somefile.txt','w')	#写入write(thing)
>>>f.write('This\nis no\nhaiku')
16
>>>f.close()
>>>f=open(r'C:\text\somefile.txt')
>>>lines=f.readlines()
>>>f.close()
>>>lines[1]="isn't a\n"
>>>f=open(r'C:\text\somefile.txt','w')
>>>f.writelines(lines)					#writelines(lines)
>>>f.close()
#最终的文本是
this
isn't a
haiku

三.迭代文件

常见的文件操作是迭代其内容,并在迭代过程中反复采取某种措施。
示例:

def process(string):
	print('Processing:',string)
1.一个字节

最简单也是最不常见的文件内容迭代方式是:在while循环中使用方法read。
示例:

with open(filename) as f:
	char=f.read(1)
	while char:
		process(char)
		char=f.read(1)

当程序运行到文本最后,方法read将返回一个空字符串;这是这个程序之所以能运行的原因。而在此之前,返回的字符串都只包含一个字符。
由于上述代码出现了重复语句,所以可以修改为

with open(filename) as f:
	while True:
	char=f.read(1)
	if not char:break
	process(char)

虽然使用break语句可能会导致代码更难以理解,但由于避免了重复语句,所以中体而言这个代码要比上一个要好。

2.一行

处理文件时,通常是迭代其中的行。
示例:

with open(filename) as f:
	with True:
		line=f.readline()
		if not line:break
		process(line)
3.所有内容

如果文件不是很大,可以一次读取整个文件;为此,可以使用方法read(将整个文件读取到一个字符串中)并不提供任何参数,也可以使用方法readlines(将文件读取到一个字符串列表中,每个字符串都是一行)
示例:

#使用read迭代字符
with open(filename) as f:
	for char in f.read():
		process(char)
#使用readlines迭代行
with open(filename) as f:
	for line in f.readlines():
		process(line)
4.延迟行迭代

有时需要迭代大型文件中的行,而使用readlines又会占用大量内存,这是可以选择使用方法fileinput(延迟行迭代——只读取实际需要的文本)。
示例:

import fileinput
for line in fileinput.input(filename):
	process(line)
5.文件迭代器

最常用的方法。由于文件是可迭代的,所以可以在for循环中直接使用它们来迭代行。
示例:

with open(filename) as f:
	for line in f:
		process(line)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值