python基础教程(第三版)学习笔记(十一)

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

from contextlib import contextmanager
import sys,pprint

f=open('xx.txt')
f.close()

文件模式
调用函数open时,如果只指定文件名,将获得一个可读取的文件对象。如果要写入文件,必须通过指定模式来显式地指出这一点。函数open的参数mode的可能取值有多个
'r' 读取模式(默认值)
'w' 写入模式
'x' 独占写入模式
'a' 附加模式
'b' 二进制模式(与其他模式结合使用)
't' 文本模式(默认值,与其他模式结合使用)
'+' 读写模式(与其他模式结合使用)
独占写入模式更进一步,在文件已存在时引发FileExistsError异常。在写入模式下打开文件时,既有内容将被删除(截断),并从文件开头处开始写入;如果要在既有文件末尾继续写入,可使用附加模式。
'+'可与其他任何模式结合起来使用,表示既可读取也可写入。例如,要打开一个文本文件进行读写,可使用'r+'。(你可能还想结合使用seek,详情请参阅本章后面的旁注“随机存取”。)请注意,'r+'和'w+'之间有个重要差别:后者截断文件,而前者不会这样做。
11.2 文件的基本方法
11.2.1 读取和写入
使用 文件对象.write来写入数据,还可使用 文件对象.read来读取数据。

f=open('xx.txt','w')
f.write('你好')
f.write('Python')
f.close()


读取也一样简单:

f=open('xx.txt','r')
w=f.read()
print(w)
f.close()
​
你好Python


------------------
(program exited with code: 0)

请按任意键继续. . .

​


如果只想输出几个字符则:

f=open('xx.txt','r')
w=f.read(4)
print(w)
​
你好Py

------------------
(program exited with code: 0)

请按任意键继续. . .

​


11.2.2 使用管道重定向输出
使用管道重定向输出需要系统命令 | 。
管道就是标准输出链接到下一个命令的标准输入。
11.2.3 读取和写入行
要读取一行(从当前位置到下一个分行符的文本),可使用方法readline。调用这个方法时,可不提供任何参数(在这种情况下,将读取一行并返回它);也可提供一个非负整数,指定readline最多可读取多少个字符。

f=open('xx.txt','r')
line=f.readline()
print(line)
f.close()
你好Python,你好Python,你好Python,你好Python,你好Python

------------------
(program exited with code: 0)

请按任意键继续. . .


11.2.4 关闭文件
要确保文件得以关闭,可使用一条try/finally语句,并在finally子句中调用close。

f=open('xx.txt')
try:
    line=f.readline()
    pass
    pass
    pass
finally:
    f.close


    

实际上,有一条好像专门为此设计的语句,那就是with语句。

with open('xx.txt','r+') as f:
    f.writelines('别忘了调用方法close将文件关闭。')
    line=f.readlines()
    print(line)
['你好Python,你好Python,你好Python,你好Python,你好Python\n', '你好sys,你好sys,你
好sys,你好sys,你好sys,你好sys,你好sys.\n', '别忘了调用方法close将文件关闭。']


------------------
(program exited with code: 0)

请按任意键继续. . .


___上下文管理器
with语句实际上是一个非常通用的结构,允许你使用所谓的上下文管理器。上下文管理器是支持两个方法的对象:__enter__和__exit__。
方法__enter__不接受任何参数,在进入with语句时被调用,其返回值被赋给关键字as后面的变量。
方法__exit__接受三个参数:异常类型、异常对象和异常跟踪。它在离开方法时被调用(通过前述参数将引发的异常提供给它)。如果__exit__返回False,将抑制所有的异常。
可以自定义上下文管理器。因为with语句只支持上下文管理协议(也就是__enter__和__exit__)的对象,以此要定义一个包含着两个方法的类。例如定义一个拷贝列表的上下文管理器:

class CopyList:
    def __init__(self,this_list):
        self.this_list=this_list
    def __enter__(self):
        self.that_list=list(self.this_list)
        return self.that_list
    def __exit__(self,type,value,tb):
        if type is None:
            self.this_list[:]=self.that_list
            
        return False
        
nums=[1,2,3,4]
with CopyList(nums) as lis:
    lis.append(7)
    lis.append(9)
print (nums)
[1, 2, 3, 4, 7, 9]


------------------
(program exited with code: 0)

请按任意键继续. . .

如在其中抛出异常,结果如下:

try:
    with CopyList(nums) as lis:
        lis.append(10)
        lis.append(12)
        raise RuntimeError
except RuntimeError as e:
    print("运行异常")

print(nums)        


 

运行异常
[1, 2, 3, 4, 7, 9]

-----------------
program exited with code: 0)

请按任意键继续

. . .


虽然对nums进行了操作但并没有生效。
with语句在控制list进入和离开其后的相关代码快时,允许对象管理所发生的事情。执行with语句是,执行方法__enter__指示正在进入的上下文,接受参数,并根据__exit__函数的返回值(true或false——false表示有异常)决定是否把处理后的返回值赋给as后的参数。
当控制流离开上下文时,就会执行__exit__(type,value,td)方法。如果没发生异常__exit__的三个参数均为None。其返回值将指引控制流离开上下文时接受__enter__的处理结果。
上下文管理器还可以利用contextlib模块提供的contextmanager包装器生成。以上例可该为:

@contextmanager
def Copylist(this_list):
    that_list=list(this_list)
    yield that_list
    this_list[:]=that_list

with CopyList(nums) as lis:
    lis.append(7)
    lis.append(9)                    #无异常
print (nums)    

try:
    with CopyList(nums) as lis:
        lis.append(10)
        lis.append(12)
        raise RuntimeError           #设定异常
except RuntimeError as e:
    print("运行异常")

print(nums)    


 

[1, 2, 3, 4, 7, 9, 7, 9]
运行异常
[1, 2, 3, 4, 7, 9, 7, 9]


------------------
(program exited with code: 0)

请按任意键继续. . .


with指引流进入上下文,函数接受参数并把值作为__enter__的返回值传递给yield,然后调用__exit__方法,调用__exit__方法时,执行将在yield语句后恢复。如上下文引发异常,它将以异常形式出现在生成器中。    
所有包含上下文管理协议的对象或被contextmanager包装的函数都可以使用with语句。
____

11.2.5 使用文件的基本方法
1、读的方法read(n)
n字节数,可选参数,默认为全部读取。

with open('xx.txt','r') as f:
    word=f.read()
    print(word)
你好Python,你好Python,你好Python,你好Python,你好Python
你好sys,你好sys,你好sys,你好sys,你好sys,你好sys,你好sys.
别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法clos
e将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘
了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将
文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调
用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件
关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方
法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭
。


------------------
(program exited with code: 0)

请按任意键继续. . .

读取部分字节:

print('*'*80)
with open('xx.txt','r') as bs:
    byte=bs.read(10)
    print(byte)
***************************************

你好Python,你


------------------
(program exited with code: 0)

请按任意键继续. . .


2、读的方法readline()
按行读取:

with open(r'xx.txt') as li:
    lis=li.readline()
    print(lis)

    

你好Python,你好Python,你好Python,你好Python,你好Python

------------------
(program exited with code: 0)

请按任意键继续. . .
with open(r'xx.txt')as li:
    lis=li.readline()
    for i in range(4):
        print(str(i)+':'+lis,end='')


        

0:你好Python,你好Python,你好Python,你好Python,你好Python
1:你好Python,你好Python,你好Python,你好Python,你好Python
2:你好Python,你好Python,你好Python,你好Python,你好Python
3:你好Python,你好Python,你好Python,你好Python,你好Python


------------------
(program exited with code: 0)

请按任意键继续. . .


3、读的方法readlines()
读取所有行。

with open('xx.txt','r') as lis:
    lines=lis.readlines()
    pprint.pprint(lines)
    print(':'*80)
    for i in lines:
        print(i)
['你好Python,你好Python,你好Python,你好Python,你好Python\n',
 '你好sys,你好sys,你好sys,你好sys,你好sys,你好sys,你好sys.\n',
 '别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法cl
ose将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别
忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close
将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了
调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文
件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用
方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关
闭。']
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

你好Python,你好Python,你好Python,你好Python,你好Python

你好sys,你好sys,你好sys,你好sys,你好sys,你好sys,你好sys.

别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法clos
e将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘
了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将
文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调
用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件
关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方
法close将文件关闭。别忘了调用方法close将文件关闭。别忘了调用方法close将文件关闭
。


------------------
(program exited with code: 0)

请按任意键继续. . .

它输出了一个有换行符的列表。
4、写的方法write(string)

with open(r'xx.txt','w') as w:
    w.write('这\n是\n一\n个\nPython\n程序')

xx.txt文件更新为:    




Python
程序

5、写的方法writelines(list)
输入列表内容。

lis=['做','程序','是一件','快乐的事!']
with open(r'xx.txt','w') as l:
    l.writelines(lis)

xx.txt文件更新为:
做程序是一件快乐的事!
lis列表字符串可以加换行符以逐行输入。此方法可结合读方法readlines实现文件内容拷贝:

with open(r'xx.txt') as r:
    w=open(r'yy.txt','w')
    rs=r.readlines()
    w.writelines(rs)


    
11.3 迭代文件
在本节的所有示例中,我都将使用一个名为process的虚构函数来表示对每个字符或行所做的处理,你可以用自己的喜欢的方式实现这个函数。下面是一个简单的示例:
def process(string):
 print('Processing:', string) 
更有用的实现包括将数据存储在数据结构中、计算总和、使用模块re进行模式替换以及添加行号。
另外,要尝试运行这些示例,应将变量filename设置为实际使用的文件的名称。

11.3.1 每次一个字符(或字节)
一种最简单(也可能是最不常见)的文件内容迭代方式是,在while循环中使用方法read。
with open(filename) as f:
 char = f.read(1)
 while char:
 process(char)
 char = f.read(1) 
以不同的方式编写循环:
with open(filename) as f:
 while True:
  char = f.read(1)
 if not char: break
 process(char)  

11.3.2 每次一行
with open(filename) as f:
 while True:
 line = f.readline()
 if not line: break
 process(line) 
11.3.3 读取所有内容
1、使用read迭代字符:
with open(filename) as f:
 for char in f.read():
 process(char) 
2、使用readlines迭代行:
with open(filename) as f:
 for line in f.readlines():
 process(line) 
11.3.4 使用 fileinput 实现延迟行迭代
这里的延迟只是指延迟是因为它只读取实际需要的文本部分。
import fileinput
for line in fileinput.input(filename):
 process(line)
11.3.5 文件迭代器 
方式1:
with open(filename) as f:
 for line in f:
 process(line) 
方式2:
for line in open(filename):
 process(line) 
与其他文件一样,sys.stdin也是可迭代的,因此要迭代标准输入(比如input输入)中的所有行,可
像下面这样做: 
import sys
for line in sys.stdin:
 process(line) 
 

import sys
for line in sys.stdin:
    print(line)


 

这是Python
这是Python

写文件比读文件难。
写文件比读文件难。

(待续)

猜你喜欢

转载自blog.csdn.net/micorjun/article/details/83819852