Python 文件处理
Python 文件处理
文件打开
我们使用 open() 函数打开文件。它需要两个参数,第一个参数是文件路径或文件名,第二个是文件的打开模式。模式通常是下面这样的:
- “r”,以只读模式打开,你只能读取文件但不能编辑/删除文件的任何内容
- “w”,以写入模式打开,如果文件存在将会删除里面的所有内容,然后打开这个文件进行写入
- “a”,以追加模式代开,写入到文件中的任何数据将自动添加到末尾
默认的模式为只读模式,也就是说如果你不提供任何模式,open() 函数将会以只读模式打开文件。我们将实验打开一个文件,不过要准备实验材料:
1 | $ wget http://labfile.oss.aliyuncs.com/courses/596/sample.txt |
然后进入 Python3 打开这个文件。
1 | >>> fobj = open("sample.txt") |
文件关闭
打开文件后我们应该总是关闭文件。我们使用方法 close() 完成这个操作。
1 | >>> fobj.close() |
始终确保你显式关闭每个打开的文件,一旦它的工作完成你没有任何理由保持打开文件。因为程序能打开的文件数量是有上限的。如果你超出了这个限制,没有任何可靠的方法恢复,因此程序可能会崩溃。每个打开的文件关联的数据结构(文件描述符/句柄/文件锁…)都要消耗一些主存资源。因此如果许多打开的文件没用了你可以结束大量的内存浪费,并且文件打开时始终存在数据损坏或丢失的可能性。
文件读取
使用 read() 方法一次性读取整个文件。
1 | >>> fobj = open("sample.txt") |
如果你再一次调用 read(),它会返回空字符串因为它已经读取完整个文件。
read(size) 有一个可选的参数 size,用于指定字符串长度。如果没有指定 size 或者指定为负数,就会读取并返回整个文件。当文件大小为当前机器内存两倍时,就会产生问题。反之,会尽可能按比较大的 size 读取和返回数据。
readline() 能帮助你每次读取文件的一行。
1 | >>> fobj = open("sample.txt") |
使用 readlines() 方法读取所有行到一个列表中。
1 | >>> fobj = open('sample.txt') |
你可以循环遍历文件对象来读取文件中的每一行。
1 | >>> fobj = open('sample.txt') |
让我们写一个程序,这个程序接受用户输入的字符串作为将要读取的文件的文件名,并且在屏幕上打印文件内容。
1 | #!/usr/bin/env python3 |
运行程序:
1 | $ ./test.py |
文件写入
让我们通过 write() 方法打开一个文件然后我们随便写入一些文本。
1 | >>> fobj = open("ircnicks.txt", 'w') |
现在读取我们刚刚创建的文件。
1 | >>> fobj = open('ircnicks.txt') |
文件操作示例程序
拷贝文件
在这个例子里我们拷贝给定的文本文件到另一个给定的文本文件。
1 | #!/usr/bin/env python3 |
你可以看到我们在这里使用了一个新模块 sys。sys.argv 包含所有命令行参数。这个程序的功能完全可以使用 shell 的 cp 命令替代:在 cp 后首先输入被拷贝的文件的文件名,然后输入新文件名。
sys.argv 的第一个值是命令自身的名字,下面这个程序打印命令行参数。
1 | #!/usr/bin/env python3 |
运行程序:
1 | $ ./argvtest.py Hi there |
这里我们用到了一个新函数 enumerate(iterableobject),在序列中循环时,索引位置和对应值可以使用它同时得到。
文本文件相关信息统计
让我们试着编写一个程序,对任意给定文本文件中的制表符、行、空格进行计数。
1 | #!/usr/bin/env python3 |
你可以看到程序有两个函数,main() 和 parse_file() ,parse_file 函数真正的分析文件并返回结果,然后在 main() 函数里打印结果。通过分割代码到一些更小的单元(函数)里,能帮助我们组织代码库并且也更容易为函数编写测试用例。
使用 with 语句
在实际情况中,我们应该尝试使用 with 语句处理文件对象,它会文件用完后会自动关闭,就算发生异常也没关系。它是 try-finally 块的简写:
1 | >>> with open('sample.txt') as fobj: |
实现 lscpu 命令
在 Linux 下你可以使用 lscpu 命令来查看当前电脑的 CPU 相关信息,如下图:
实际上 lscpu 命令是读取 /proc/cpuinfo 这个文件的信息并美化输出,现在你可以自己写一个 Python 程序以只读模式读取 /proc/cpuinfo 这个文件,然后打印出来,这样你就有自己的一个 Python 版本的 lscpu 命令了 :)
记得一行一行的读取文本文件,不要一次性读取整个文件,因为有时候你读取的文件可能比可用内存还大。