首页 > Python笔记 阅读数:27

Python open():打开文件

文件是指记录在存储介质上的一组相关信息集合。在操作系统下,文件名由文件主名和扩展名(可选项)组成,二者之间用一个小圆点隔开。如在“Readme.txt”文件中,“Readme”是文件主名,“txt”为扩展名。

Python 使用 open( ) 方法以读文件的方式打开文件,传入文件名与标识符,格式如下:

file = open('filename.txt', mode = 'r' )


其中,file 就是一个文件对象,filename 是我们希望打开的文件的字符串名称(如果它和当前 .py 文件不在同一个路径下,则 filename 中要包括文件的路径信息),mode 表示读写模式,默认为只读(read)模式。

假设我们有一个文件,名为 python.txt。我们可通过如下代码打开它:
In [1]: fhand = open('python.txt', 'r')
In [2]: print(fhand)
<_io.TextIOWrapper name= 'python.txt'  mode= 'r' encoding= 'UTF-8'>

在 In [1] 处,如果文件不存在,则会抛出 FileNotFoundError 异常。Python 文件的打开模式有许多种,如表 1 所示。

表 1:Python 文件的打开模式
模式 描述
'r'      
以只读(read )模式打开文件.若文件不存在则会报错。文件指针指向文件开头(默认)
'w' 
以只写(write )模式打开文件,若文件不存在则创建filename指定的文件,若文件存在则覆盖旧文件
'a' 
以追加(append )模式打开文件,若文件存在,文件指针会指向文件尾部,也就是说新内容会 追加到旧文件的末尾,如果文件不存在,则创建文件用于写入
't'  以文本文件(text )模式打开文件(默认)
'b'  以二进制(binary )模式打开文件.主要用于打开非文本文件.如图片、音频等
'+'  打开文件并允许更新(可读、可写)

表 1 中所列的模式是可以组合的,例如,“rb”表示以二进制只读模式打开文件。再例如,“ab+”表示以二进制模式打开文件,并且把新数据追加到文件的尾部,如果该文件不存在,则需创建文件。

对于文本文件而言,它可视为由很多行字符文本构成的文件。如果文件存在,打开文件之后,就可以利用for循环逐行读取,也可以使用 read( ) 方法一次性读取文件的全部内容,然后用 print( ) 函数将读取的文件内容打印出来,最后调用 close( ) 方法关闭文件。
In [3]: for line in fhand:
             print(line)
程序执行结果为:

In this tutoriml, you'll learn about Python operator precedence and associativity.
This topic is crucial for programmers to understand the semantics of Python operators.
After reading it, you should be able to know how Python evaluates the order of its operators.
….(文本文件内容,省略部分)


当然,我们还可以用 read( ) 方法将文本文件的所有数据一次性读取出来,然后用 print( ) 打印出来。
In [4]: txt = fhand.read()
In [5]: print(txt)

虽然上述代码语法无误,但在当前上下文环境下,不会有任何输出。

为什么会这样呢?这是因为,为了方便处理文件,文件对象会维护一个文件指针,文件指针会记录当前文件所在的位置,以 In [3] 处的 for 循环为例,每次输出一行都会以换行符(\n)作为标记,输出数据时,文件指针也会随之下行,待 for 循环结束时,文件指针会指向文件尾部(EOF,end of file)。此时,再次使用 read( ) 方法,该文件指针“进无可进”,如图 1 所示。


图 1:读取文件操作示意图

解决上述问题的办法也很简单。就是将文件指针复位,这时就需要利用 seek( ) 方法。seek( ) 用于将文件读取指针移动到指定位置,该方法的原型如下:

fileObject.seek(offset[,whence])


其中,offset 表示开始的偏移量,也就是需要偏移的字节数。whence 为可选参数,默认值为 0,表示要从哪个位置开始偏移。0  代表将文件开头作为起点,1 代表从当前位置开始算起,2 代表从文件末尾算起。

根据上面的描述,我们把 seek( ) 方法的参数设置为 0 即可解决问题,代码如下:
In [6]: fhand. seek (0) #将文件指针复位到起始点
Out[6]: 0
In [7]: txt = fhand.read ()
In [8]: print (txt)
In this tutorim丄,you' 11 learn about Python operator precedence and associativity. This topic is crucial for programmers to understand the semantics of Python operators.
……(文本文件内容,省略部分)

上面代码中的 read( ) 方法主要用于从文件中读取指定的字节数,若未设定参数或参数为负,则读取文件中的所有数据。所以我们可以显式设置读取的字节数量,达到“自主可控”的读取效果。
In [9]: fhand.tell()
Out[9]: 444
In [10]: fhand.seek(0)
Out[10]: 0
In [11]: fhand.read(20)
Out[11]: 'In this tutorial, yo'

在 In [7] 处,由于没有设置 read( ) 方法的参数,因此默认读取所有的数据,此时文件的指针指向文件的尾部。在 In [9] 处,我们使用 tell( ) 方法返回文件指针的当前位置。由于此时文件指针在文件的尾部,所以 tell( ) 给出的值实际上是整个文本的字节数,即间接给出了文本文件的大小。

为了进一步对文件进行操作,我们在 In [10] 处复位文件指针,让它重新指向文件起始处。然后在 In [11] 处,read(20) 表示从文件开始处读取 20 个字节的数据。

相关文章