python操作文本文件

打开与关闭文件

在磁盘上读写文件之前,必须先打开这个文件。打开文件就需要提供文件的路径。

在与Python程序同一个目录下,我们有一个名为pi.txt的文件,它的内容如下:

3.1415926535898

现在使用Python来打开和关闭它:

fhand = open ('pi.txt')         # 打开文件
fhand.close()                   # 关闭文件

执行此程序不会有任何输出,这表示着打开和关闭文件都得到了正确执行。

可以看到,使用open()函数打开文件,参数为文件名(或文件路径);该函数会返回一个文件句柄,文件句柄并不会实际保存文件的内容,而是代表着一种操作,在上面的例子中,文件句柄被赋值给变量fhand

打开文件后,程序具有读(默认)该文件的权限。

最后,使用文件句柄的close()方法关闭文件。这非常重要,因为使用完而没有关闭的文件会占用内存或造成安全问题。

如果Python找不到该文件,则会返回错误,比如下面这样:

Traceback (most recent call last):
  File "open_file.py", line 8, in <module>
    fhand = open ('pii.txt')         # 打开文件
FileNotFoundError: [Errno 2] No such file or directory: 'pii.txt'

Python提示我们没有相应的文件或者目录: ‘pii.txt’。

打开文件后就可以对文件进行操作:

fhand = open ('pi.txt')         
file_content = fhand.read()     # 读取文件内容
file_content = file_content.rstrip()    # 去掉末尾的换行符
print (file_content)            # 输出
fhand.close()                   

fhand.read()方法将文件内容作为一个字符串返回。

文件中的每一行末尾使用换行符\n表示换行,例子中方法rstrip()去掉文本中的换行符,然后输出。

程序的运行效果如下:

 python open_file.py 3.1415926535898 

如果在文件关闭之前程序发生BUG意外退出,则文件不会关闭,为了避免此类事件的发生,可以使用with语句:

with open('pi.txt') as fhand:
    file_content = fhand.read()
    file_content = file_content.rstrip()
    print (file_content)

with语句的特点是即便在操作文件时发生错误,文件也会自动被清理。

读取文本行

fhand.read()虽然可以读取文本内容,但是当我们想要逐行处理文件内容,或者文件很大而无法一次性加载进内存的时候,就不适用了。

可以使用for语句逐行处理文件内容:

filename = 'when_old.txt'

count = 0
with open (filename) as fhand:
    for line in fhand:
        count = count + 1
print ('总共的行数: %d' % (count))

本程序中将文件名保存在变量filename中。

打开文件后,使用for语句按行读取文件内容。例子中,每次循环依次取一行文本以字符串的格式保存在变量line中,每次循环中变量count自增1。

这个程序的作用是,打开程序所在目录的when_old.txt文件,然后统计行数,并输出结果。

when_old.txt文件的内容是:

When you are old
William Butler Yeats

When you are old and grey and full of sleep,
And nodding by the fire,take down this book,
And slowly read,and dream of the soft look
Your eyes had once,and of their shadows deep;
How many loved your moments of glad grace,
And loved your beauty with love false or true,
But one man loved the pilgrim Soul in you
And loved the sorrows of your changing face;
And bending down beside the glowing bars,
Murmur,a little sadly,how Love fled
And paced upon the mountains overhead
And hid his face amid a crowd of stars.

可以使用其他方法操作字符串line

filename = 'when_old.txt'
with open(filename) as fhand:
    for line in fhand:
        line = line.rstrip()
        if line.startswith ('And'):
            print (line)

程序将以'And'开头的行打印出来。

写文件

打开文件后,默认的权限是读(r),如果要写文件,则需要使用写(w)或者追加(a)权限。

w权限,打开一个文件用于写入。如果该文件存在,则覆盖该文件;如果该文件不存在,则创建该文件。

a权限,打开一个文件用于追加。如果该文件存在,在文件末尾追加;如果该文件不存在,则创建该文件。

下面是一个使用w权限打开文件的例子:

filename = "when_old.txt"
with open (filename ,'w') as fhand:
    fhand.write ('When you are old\n')
    fhand.write ('William Butler Yeats\n')

例子中使用w权限打开该文件,并写入两行。(如果该文件存在,则内容会被覆盖)

fhand.write()不会自动添加换行符,所以如果需要换行,需在末尾添加\n

统计词频程序

下面我们写一个统计文件中词频的程序。

它会统计文件中各个词的出现的次数,然后由高到低显示出前5个词。

首先我们完成打开和关闭文件的程序内容:

filename = input ('请输入文件名:')

try:
    fhand = open (filename)
except:
    print ('打开文件出错:' , filename)
    exit ()

fhand.close()

在例子中,由用户输入文件名,并且使用异常捕获以处理文件打开时的错误。

下面对内容进行统计:

counts = dict()
for line in fhand:
    line = line.rstrip()
    words = line.split()        # 分割单词,以列表返回
    for word in words:
        if word in counts:
            counts[word] += 1
        else:
            counts[word] = 1

这个程序:

  • 首先创建一字典counts,存放单词和它出现的次数。
  • 依次处理文件中的每一行。
  • 使用rstrip()方法去掉每行末尾的换行符。
  • 使用split()方法将字符串按空白字符分割,并作为列表返回。这样列表words保存了本行的单词,每个单词都是列表中的一个值。
  • 对于单词列表words,处理其中的每个单词。
  • 如果单词作为键在字典counts中,则其值自增1.
  • 如果单词作为键不在字典counts中,则为其值赋值1.

如此,我们就在字典中存放了单词:次数的键值对。

由于字典不能保存顺序,所以不能对其进行排序。为此,将每个键值对都添加到一个列表中:

word_list = list()
for key, val in counts.items():
    word_list.append((val,key))

在列表word_list中,每一项都是一个元组,每个元组第一个值是单词出现的次数,第二个值是单词内容。

对其进行逆向(由大到小)排序:

word_list.sort (reverse=True)

打印最终结果:

print ('FREQ \t WORD')
for key, val in word_list[:5]:
     print ('%d \t %s' % (key, val))

整个程序如下:

filename = input ('请输入文件名:')
# filename = 'when_old.txt'

try:
    fhand = open (filename)
except:
    print ('打开文件出错:' , filename)
    exit ()

counts = dict()
for line in fhand:
    line = line.rstrip()
    words = line.split()        # 分割单词,以列表返回
    for word in words:
        if word in counts:
            counts[word] += 1
        else:
            counts[word] = 1

fhand.close()

# print (counts)

word_list = list()
for key, val in counts.items():
    word_list.append((val,key))

word_list.sort (reverse=True)

print ('FREQ \t WORD')
for key, val in word_list[:5]:
     print ('%d \t %s' % (key, val))

下面是程序运行结果的示例:

$ python word_frequency.py 
请输入文件名:when_old.txt
FREQ     WORD
7    And
6    the
6    of
4    loved
3    your

发表评论

电子邮件地址不会被公开。 必填项已用*标注