跳转到内容

Python 初学者教程/文件 I/O

来自维基教科书,开放的书籍,开放的世界

在上节课中,我们学习了如何将外部代码加载到我们的程序中。无需任何介绍(就像我通常的做法),让我们深入研究使用普通文本文件的文件输入和输出,以及随后保存和恢复类的实例。(哇,我们的术语能力已经大大提高了!)

打开文件

[编辑 | 编辑源代码]

要打开一个文本文件,可以使用 open() 函数。看起来很合理。您需要向 open() 传递某些参数,告诉它以何种方式打开文件 - 'r' 表示只读,'w' 表示只写(如果存在旧文件,它将被覆盖),'a' 表示追加(在文件末尾添加内容)和 'r+' 表示读写。但少说点,让我们打开一个文件进行读取(您可以在 Python IDLE 模式下执行此操作)。打开一个普通的文本文件。然后,我们将打印出我们在文件中读取的内容

代码示例 1 - 打开文件
openfile = open('pathtofile', 'r')
openfile.read()

这很有趣。你会注意到很多 '\n' 符号。这些代表换行符(你在哪里按下回车键以开始新的一行)。文本完全没有格式化,但如果要将 openfile.read() 的输出传递给 print(通过键入 print openfile.read()),它将被很好地格式化。

寻找你所需要的东西

[编辑 | 编辑源代码]

你尝试过键入 print openfile.read() 吗?它失败了吗?它很可能失败了,原因是“光标”改变了位置。光标?什么光标?好吧,一个你真的看不见的光标,但它仍然是一个光标。这个看不见的光标告诉 read 函数(以及许多其他 I/O 函数)从哪里开始。要设置光标的位置,可以使用 seek() 函数。它以 seek(offset, whence) 的形式使用。

whence 是可选的,它决定从哪里开始查找。如果 whence 为 0,则字节/字母从开头开始计数。如果它为 1,则字节从当前光标位置开始计数。如果它为 2,则字节从文件末尾开始计数。如果没有在那里输入任何内容,则假定为 0。

offset 描述光标移动到 whence 的距离。例如

openfile.seek(45,0) 会将光标移动到文件开头后的 45 个字节/字母。openfile.seek(10,1) 会将光标移动到当前光标位置后的 10 个字节/字母。openfile.seek(-77,2) 会将光标移动到文件末尾之前的 77 个字节/字母(注意 77 之前的 -)。现在试试吧。使用 openfile.seek() 转到文件中的任何位置,然后尝试键入 print openfile.read()。它将从您查找的位置开始打印。但请意识到 openfile.read() 会将光标移动到文件末尾 - 您需要再次查找。

其他 I/O 函数

[编辑 | 编辑源代码]

还有许多其他函数可以帮助您处理文件。它们有很多用途,可以使您更强大,让您所做的事情变得更容易。让我们看看 tell()、readline()、readlines()、write() 和 close()。

tell() 返回光标在文件中的位置。它没有参数,只需键入它即可(就像下面的示例将显示的那样)。这对于知道您正在引用什么、它在哪里以及对光标的简单控制非常有用。要使用它,键入 fileobjectname.tell() - 其中 fileobjectname 是您打开文件时创建的文件对象名称(在 openfile = open('pathtofile', 'r') 中,文件对象名称是 openfile)。

readline() 从光标所在位置读取到行尾。请记住,行尾不是屏幕的边缘 - 当您按下回车键以创建新行时,该行结束。这对读取事件日志或逐步处理某些内容非常有用。您不需要向 readline() 传递任何参数,尽管您可以选择性地告诉它要读取的最大字节/字母数,方法是在括号中放入一个数字。将其与 fileobjectname.readline() 一起使用。

readlines() 类似于 readline(),但是 readlines() 从光标开始读取所有行,并返回一个列表,每个列表元素包含一行代码。将其与 fileobjectname.readlines() 一起使用。例如,如果您有以下文本文件

代码示例 2 - 示例文本文件
Line 1

Line 3
Line 4

Line 6

从 readlines() 返回的列表将是

表 1 - readlines 返回的列表
索引
0 '第 1 行'
1 ''
2 '第 3 行'
3 '第 4 行'
4 ''
5 '第 6 行'

write() 函数将写入文件。你怎么猜到的?它从光标所在的位置开始写入,并覆盖前面的文本 - 就像在 MS Word 中,您按下“插入”键,它就会覆盖旧文本。要使用这个最有用的函数,在括号中放入一个字符串以进行写入,例如 fileobjectname.write('这是一个字符串')。

close,您可能会想到,会关闭文件,这样您就不能再读取或写入它,直到再次打开它。很简单。要使用它,您需要写入 fileobjectname.close()。简单!

在 Python IDLE 模式下,打开一个测试文件(或创建一个新的...),并使用这些函数进行练习。您可以进行一些简单的(非常不方便的)文本编辑。

在 Python 中,pickle 是保存到文件的对象。在这种情况下,对象可以是变量、类的实例、列表、字典或元组。其他事物也可以被 pickle,但有限制。该对象可以稍后恢复或取消 pickle。换句话说,您正在“保存”您的对象。

那么我们如何 pickle 呢?使用 dump() 函数,该函数位于 pickle 模块中 - 因此在程序开始时,您需要写入 import pickle。很简单吧?然后打开一个空文件,并使用 pickle.dump() 将对象放入该文件中。让我们试试这个

代码示例 3 - pickletest.py
### pickletest.py
### PICKLE AN OBJECT

# import the pickle module
import pickle

# lets create something to be pickled
# How about a list?
picklelist = ['one',2,'three','four',5,'can you count?']

# now create a file
# replace filename with the file you want to create
file = open('filename', 'wb')

# now let's pickle picklelist
pickle.dump(picklelist,file)

# close the file, and your pickling is complete
file.close()

首先,我们打开 'filename' 以写入二进制数据 (wb) - open('filename', 'wb')

然后,我们将我们的列表转储到二进制文件。

执行此操作的代码如下所示:pickle.dump(object_to_pickle, file_object),其中

  • object_to_pickle 是您要 pickle 的对象(即将其保存到文件)
  • file_object 是您要写入的文件对象(在本例中,文件对象是 'file')

在关闭文件后,在记事本中打开它,看看您看到了什么。除了其他一些乱七八糟的东西,您会看到我们创建的列表的部分内容。

现在重新打开或取消 pickle 文件。要使用此功能,我们可以使用 pickle.load()

代码示例 4 - unpickletest.py
### unpickletest.py
### unpickle file

# import the pickle module
import pickle

# now open a file for reading
# replace filename with the path to the file you created in pickletest.py
unpicklefile = open('filename', 'rb')

# now load the list that we pickled into a new object
unpickledlist = pickle.load(unpicklefile)

# close the file, just for safety
unpicklefile.close()

# Try out using the list
for item in unpickledlist:
  print item

很不错,对吧?

当然,上面的限制是,我们只能在一个文件中放置一个对象。我们可以通过将许多可 pickle 的对象放入列表或字典中,然后 pickle 该列表或字典来解决这个问题。这是最快捷、最简单的方法,但如果您对 pickle 有深入的了解,您可以做一些非常高级的事情。

或者,我们可以使用多个“pickle.dump(list, file)”函数:[1]

# pickle multiple lists
pickle.dump(list_1, file)
pickle.dump(list_2, file) 
...

以及多个“pickle.load(file)”函数

# unpickle multiple lists
list_read_1 = pickle.load(file)
list_read_2 = pickle.load(file) 
...

我们不会在这里介绍复杂的例子。

参考资料

[编辑 | 编辑源代码]
华夏公益教科书