Python 基础学习13:文件

Python 通过文件和文件流能够永久存储数据以及处理来自其它程序的数据。

打开文件

函数 open 来自于自动导入的模块 io 中。
函数必须指定文件名作为参数,然后返回一个文件对象,如果文件不存在将引发异常:

>>> f  = open('demofile.txt')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'demofile.txt'

文件模式

调用函数 open 时,如果只指定文件名,获得的是一个可读取的文件对象。如果要写入文件必须通过显式的指定模式。
open 函数接受 mode 参数来指定模式,有以下模式可用:

描述
‘r’读取模式(默认)
‘w’写入模式
‘x’独占写入模式
‘a’附加模式
‘b’二进制模式(可结合其它模式使用)
‘t’文本模式(默认值,可结合其它模式使用)
‘+’读写模式(可与其它模式结合使用

其中 w 写入模式能够写入文件,并且文件不存在时可以创建文件。
+ 可与其它任何模式结合使用,表示既可以读取也可以写入。
默认模式 rt 代表将文件视为经过编码的 Unicode 文本,因此将自动执行解码和编码,默认使用 UTF-8 编码,可以通过 encodingerrors 关键字参数来指定其它编码和 Unicode 错误处理策略。
如果文件包含非文本数据,例如图片,需要使用二进制模式(例如 rb)来禁用与文本相关的功能。

文件的基本方法

打开文件后,对于文件对象有一些基本的方法,以及其它类似于文件的对象(也称为流)。
sys 模块中就包含了三个标准流 sys.stdin sys.stdout sys.stderr

读取和写入

文件最重要的功能就是提供和接收数据。
如果有一个文件对象是 f ,可以通过 f.write 写入数据,f.read 读取数据。在文本和二进制模式下,基本上分别将 strbytes 类用作数据。

每次调用 f.write(string) 时,提供的字符串都将写入到文件中既有内容的后面:

>>> f = open('demofile.txt', 'w')
>>> f.write('hello')
5
>>> f.write('world')
5
>>> f.close()

读取文件内容时,可以告诉流需要读取多少字符:

>>> f = open('demofile.txt')
>>> f.read(5)
'hello'
>>> f.read(5)
'world

使用管道重定向输出

在 Bash 中,可以通过管道依次将多个命令链接起来,类似于 cat somefile.txt | python somescript.py | sort ,如何在 Python 中获取标准输入呢?
参考示例:

import sys

text = sys.stdin.read()
words = text.split()
wordcount = len(words)
print('Wordcount: ', wordcount)

通过 sys.stdin 流,然后调用 read 方法来获取数据。

流默认是按顺序从头到尾读取,可以通过 seektell 方法在文件中移动,值访问感兴趣的内容,称为随机存取。

>>> f = open('demofile.txt', 'w')
>>> f.write('0123456789')
10
>>> f.seek(5)
5
>>> f.write('Hello, World!')
13
>>> f.close()
>>> f = open('demofile.txt')
>>> f.read()
'01234Hello, World!'

tell() 返回当前位于文件的位置:

>>> f = open('demofile.txt')
>>> f.read(3)
'012'
>>> f.read(2)
'34'
>>> f.tell()
5

读取和写入行

要读取一行(从当前位置到一个分行符的文本),可使用 readline 方法,也可以提供一个非负数的整数,来指定最多可读取多少个字符。
要读取文件中所有行,并以列表的方式返回,可以使用 readlines 方法。
wirtelines 接受一个字符串列表(可以是任何序列或可迭代的对象),然后将这些字符串都写入到文件(或流)中,写入时不会自动添加换行。

关闭文件

程序退出时将自动关闭文件对象,因此是否将读取的文件关闭其实影响不大。
对于写入的文件,一定要将其关闭,因为 Python 会缓存写入的额数据,只有关闭时才会写入到磁盘中,如果不想关闭,但是希望数据落盘可以使用 flush 方法。
只要能够方便的关闭文件,就应该将其关闭。

可以使用 try/finally 语句:

>>> try:
     f = open('demofile.txt', 'w')
     f.write('hello')
finally: f.close()

5

但还是很麻烦,Python 存在一个上下文管理器方便自动关闭文件对象:

>>> with open('demofile.txt', 'w') as f:
        f.write('world')

5

达到语句末尾时,将自动关闭文件,即便出现异常也是如此,这样就很方便了。

迭代文件内容

一种常见的文件操作是迭代文件中的内容。

每次一个字符(或字节)

while 循环中使用方法 read 来遍历文件中每个字符(二进制模式下是每个字节):

def process(string):
    print('Processing: ', string)

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

每次一行

使用 readline 可实现行读取,然后进行迭代:

def process(string):
    print('Processing: ', string)

​with open('somefile.txt') as f:
    ​while True:
        line = f.readline()
        if not line: break
        process(line)

读取所有内容

如果文件不大,可以一次读取整个文件,直接使用 read() 即可,也可以通过 readlines() 来获取包含整个文件内容的行列表。

使用 read 迭代字符:

def process(string):
    print('Processing: ', string)

with open('somefile.txt') as f:
    for char in f.read():
        process(char)

使用 readlines 迭代行:

def process(string):
    print('Processing: ', string)

with open('somefile.txt') as f:
    for line in f.readlines():
        process(line)

使用 fileinput 实现延迟迭代

对大型文件进行迭代行的时候,readlines 将占用大量的内存,可以选择 while 配合 readline 实现,但是在 Python 中,在可能的情况下,尽可能选择 for 循环。可以使用一种名为延迟行迭代的方法——因此它只读取实际需要的文本部分。

使用 fileinput 迭代行:

import fileinput

def process(string):
    print('Processing: ', string)

for line in fileinput.input('demofile.txt'):
    process(line)

文件迭代器

文件实际上是可以迭代的,意味着可以在 for 循环中直接使用它们进行迭代:

def process(string):
    print('Processing: ', string)

with open('somefile.txt') as f:
    for line in f:
        process(line)

sys.stdin 也是可以迭代的,因此要迭代标准输入中的所有行,可以这样做:

import sys

for line in sys.stdin:
    process(line)

可对迭代器做的事情基本上可以对文件做,例如使用 list(open(filename)) 将其转换为字符列表,效果与 readlines 相同。

示例:

>>> f = open('somefile.txt', 'w')
>>> print('First', 'line', file=f)
>>> print('Second', 'line', file=f)
>>> print('Third', 'and final', 'line', file=f)
>>> f.close()

>>> lines = list(open('somefile.txt'))
>>> lines
['First line\n', 'Second line\n', 'Third and final line\n']

>>> first, second, third = open('somefile.txt')
>>> first
'First line\n'
>>> second
'Second line\n'
>>> third
'Third and final line\n'

示例:

>>> f = open('somefile.txt', 'w')
>>> print('First', 'line', file=f)
>>> print('Second', 'line', file=f)
>>> print('Third', 'and final', 'line', file=f)
>>> f.close()

>>> lines = list(open('somefile.txt'))
>>> lines
['First line\n', 'Second line\n', 'Third and final line\n']

>>> first, second, third = open('somefile.txt')
>>> first
'First line\n'
>>> second
'Second line\n'
>>> third
'Third and final line\n'

对打开的文件进行序列解包,这种操作不常见,因为有时不知道文件有多少行。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

滚动至顶部