原文: http://zetcode.com/lang/python/files/

在 Python 编程教程的这一部分中,我们处理文件以及标准输入和输出。 我们展示了如何从文件读取和写入文件。 我们简要介绍pickle模块。

Python 中的所有内容都是一个对象。 UNIX 中的所有内容都是文件。

Python open函数

open()函数用于在 Python 中打开文件。

  1. open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None)

file是要打开的文件的名称。 mode指示如何打开文件:用于读取,写入或附加。 buffering是用于设置缓冲策略的可选整数。 encoding是用于解码或编码文件的编码名称。 errors是一个可选的字符串,它指定如何处理编码和解码错误。 newline控制换行符的行为。

文件模式为:

模式 含义
'r' 读取(默认)
'w' 写入
'a' 附加
'b' 二进制数据
'+' 更新(读写)
'X' 互斥创建,如果文件存在则失败

在以下示例中,我们使用此文本文件。

works.txt

  1. Lost Illusions
  2. Beatrix
  3. Honorine
  4. The firm of Nucingen
  5. Old Goriot
  6. Colonel Chabert
  7. Cousin Bette

Python with 语句

处理文件通常会导致错误; 因此,我们必须管理可能的异常。 另外,当不再需要文件对象时,必须关闭该文件对象。 with语句通过封装通用的准备和清除任务来简化异常处理。 它还会自动关闭打开的文件。

read_width.py

  1. #!/usr/bin/env python
  2. # read_width.py
  3. with open('works.txt', 'r') as f:
  4. contents = f.read()
  5. print(contents)

该示例读取works.txt文件的内容。

  1. with open('works.txt', 'r') as f:

通过open()函数,我们打开works.txt文件进行读取。 文件对象的别名为fwith语句负责处理异常和关闭打开的文件。

  1. contents = f.read()

read()方法读取所有内容,直到 EOF。 它将数据作为一个大字符串返回。

Python 读取函数

read()函数从文件中读取指定数量的字节。 如果未指定字节数,它将读取整个文件。

read_data.py

  1. #!/usr/bin/env python
  2. # read_data.py
  3. import sys
  4. with open('works.txt', 'r') as f:
  5. print(f.read(5))
  6. print(f.read(9))

该代码示例从文件中读取了五个字母,并将它们打印到控制台。 然后读取并打印另外九个字母。 第二个操作继续从第一个操作结束的位置读取。

  1. $ ./read_data.py
  2. Lost
  3. Illusions

这是输出。

Python 文件位置

文件位置是我们从中读取数据的文件位置。 tell()方法给出文件中的当前位置,seek()方法移动文件中的位置。

file_positions.py

  1. #!/usr/bin/env python
  2. # file_positions.py
  3. with open('works.txt', 'r') as f:
  4. print(f.read(14))
  5. print(f"The current file position is {f.tell()}")
  6. f.seek(0, 0)
  7. print(f.read(30))

在示例中,我们读取 14 个字节,然后确定并打印当前文件位置。 我们将当前文件位置移到seek()的开头,再读取 30 个字节。

  1. $ ./file_positions.py
  2. Lost Illusions
  3. The current file position is 14
  4. Lost Illusions
  5. Beatrix
  6. Honorin

这是输出。

Python readline方法

readline()方法从文件读取一行。 字符串中保留尾随换行符。 函数到达文件末尾时,将返回一个空字符串。

readbyline.py

  1. #!/usr/bin/env python
  2. # readbyline.py
  3. with open('works.txt', 'r') as f:
  4. while True:
  5. line = f.readline()
  6. if not line:
  7. break
  8. else:
  9. print(line.rstrip())

使用readline()方法和while循环,我们从文件中读取了所有行。

  1. while True:

我们开始无止境的循环; 因此,我们稍后必须使用break语句跳过循环。

  1. line = f.readline()

从文件中读取一行。

  1. if not line:
  2. break
  3. else:
  4. print(line.rstrip())

如果到达 EOF,则调用break语句; 否则,我们将该行打印到控制台,同时在该行的末尾删除换行符。

在下面的示例中,我们使用一种更方便的方式浏览文件的各行。

read_file.py

  1. #!/usr/bin/env python
  2. # read_file.py
  3. with open('works.txt', 'r') as f:
  4. for line in f:
  5. print(line.rstrip())

在内部,文件对象是迭代器。 我们可以将文件对象传递给for循环来遍历它。

Python readlines方法

readlines()方法读取数据,直到文件结尾,然后返回行列表。

readlines.py

  1. #!/usr/bin/env python
  2. # readlines.py
  3. with open('works.txt', 'r') as f:
  4. contents = f.readlines()
  5. for i in contents:
  6. print(i.strip())

readlines()方法将文件的所有内容读入内存。 但是,对于非常大的文件,这可能会出现问题。

Python write方法

write()方法将字符串写入文件。

strophe.py

  1. #!/usr/bin/env python
  2. # strophe.py
  3. text = '''Incompatible, it don't matter though
  4. 'cos someone's bound to hear my cry
  5. Speak out if you do
  6. You're not easy to find\n'''
  7. with open('strophe.txt', 'w') as f:
  8. f.write(text)

这次我们以"w"模式打开文件,以便我们可以对其进行写入。 如果该文件不存在,则会创建它。 如果存在,它将被覆盖。

  1. $ cat strophe.txt
  2. Incompatible, it don't matter though
  3. 'cos someone's bound to hear my cry
  4. Speak out if you do
  5. You're not easy to find

Python 标准 I/O

基本的 I/O 连接共有三种:标准输入,标准输出和标准错误。 标准输入是进入程序的数据。 标准输入来自键盘。 标准输出是我们使用 print 关键字打印数据的地方。 除非重定向,否则它是终端控制台。 标准错误是程序写入错误消息的流。 通常是文本终端。

Python 中的标准输入和输出是sys模块中的对象。

对象 描述
sys.stdin 标准输入
sys.stdout 标准输出
sys.stderr 标准错误

符合 UNIX 的哲学,标准 I/O 流是文件对象。

Python 标准输入

标准输入是进入程序的数据。

read_name.py

  1. #!/usr/bin/env python
  2. # read_name.py
  3. import sys
  4. print('Enter your name: ', end='')
  5. name = ''
  6. sys.stdout.flush()
  7. while True:
  8. c = sys.stdin.read(1)
  9. if c == '\n':
  10. break
  11. name = name + c
  12. print('Your name is:', name)

read()方法从标准输入读取一个字符。 在我们的示例中,系统提示您输入'Enter your name: '。 我们输入名称,然后按EnterEnter键生成new line字符:\n

  1. $ ./read_name.py
  2. Enter your name: Peter
  3. Your name is: Peter

为了获得输入,我们可以使用更高级别的函数:input()raw_input()

如果提供了input()函数,则会打印提示并读取输入。

input_example.py

  1. #!/usr/bin/env python
  2. # input_example.py
  3. data = input('Enter value: ')
  4. print('You have entered:', data)
  1. $ ./input_example.py
  2. Enter value: Hello there
  3. You have entered: Hello there

Python 标准输出

标准输出是我们打印数据的地方。

std_output.py

  1. #!/usr/bin/env python
  2. # std_output.py
  3. import sys
  4. sys.stdout.write('Honore de Balzac, Father Goriot\n')
  5. sys.stdout.write('Honore de Balzac, Lost Illusions\n')

在示例中,我们将一些文本写入标准输出。 在我们的例子中,这是终端控制台。 我们使用write()方法。

  1. $ ./stdout.py
  2. Honore de Balzac, Father Goriot
  3. Honore de Balzac, Lost Illusions

默认情况下,print函数将一些文本放入sys.stdout

print_fun.py

  1. #!/usr/bin/env python
  2. # print_fun.py
  3. print('Honore de Balzac')
  4. print('The Splendors and Miseries of Courtesans', 'Gobseck', 'Father Goriot', sep=":")
  5. vals = [1, 2, 3, 4, 5]
  6. for e in vals:
  7. print(e, end=' ')
  8. print()

在此示例中,我们使用sepend参数。 sep分隔打印的对象,end定义最后打印的内容。

  1. $ ./print_fun.py
  2. Honore de Balzac
  3. The Splendors and Miseries of Courtesans:Gobseck:Father Goriot
  4. 1 2 3 4 5

这是输出。

可以使用print()函数写入文件。 print()函数包含一个file参数,该参数告诉我们在哪里打印数据。

print2file.py

  1. #!/usr/bin/env python
  2. # print2file.py
  3. with open('works.txt', 'w') as f:
  4. print('Beatrix', file=f)
  5. print('Honorine', file=f)
  6. print('The firm of Nucingen', file=f)

我们打开一个文件,并在其中写入巴尔扎克的书的三个书名。 文件对象被赋予file参数。

  1. $ cat works.txt
  2. Beatrix
  3. Honorine
  4. The firm of Nucingen

Python 重定向

标准输出可以重定向。 在以下示例中,我们将标准输出重定向到常规文件。

redirect.py

  1. #!/usr/bin/env python
  2. # redirect.py
  3. import sys
  4. with open('output.txt', 'w') as f:
  5. sys.stdout = f
  6. print('Lucien')
  7. sys.stdout.write('Rastignac\n')
  8. sys.stdout.writelines(['Camusot\n', 'Collin\n'])
  9. sys.stdout = sys.__stdout__
  10. print('Bianchon')
  11. sys.stdout.write('Lambert\n')

redirect.py脚本中,我们将标准输出重定向到常规文件output.txt。 然后,我们恢复原始的标准输出。 std.output的原始值保存在特殊的sys.__stdout__变量中。

  1. $ ./redirect.py
  2. Bianchon
  3. Lambert
  4. $ cat output.txt
  5. Lucien
  6. Rastignac
  7. Camusot
  8. Collin

Python pickle模块

到目前为止,我们一直在处理简单的文本数据。 如果我们使用对象而不是简单的文本怎么办? 在这种情况下,我们可以使用pickle模块。 此模块序列化 Python 对象。 Python 对象将转换为字节流并写入文本文件。 此过程称为酸洗。 从文件读取并重建对象的逆操作称为反序列化或解腌。

pickle_ex.py

  1. #!/usr/bin/env python
  2. # pickle_ex.py
  3. import pickle
  4. class Person:
  5. def __init__(self, name, age):
  6. self.name = name
  7. self.age = age
  8. def get_name(self):
  9. return self.name
  10. def get_age(self):
  11. return self.age
  12. person = Person('Monica', 15)
  13. print(person.get_name())
  14. print(person.get_age())
  15. with open('monica', 'wb') as f:
  16. pickle.dump(person, f)
  17. with open('monica', 'rb') as f2:
  18. monica = pickle.load(f2)
  19. print(monica.get_name())
  20. print(monica.get_age())

在我们的脚本中,我们定义一个Person类。 我们创建一个人。 我们使用dump()方法腌制对象。 我们关闭文件,再次打开以进行读取,然后使用load()方法解开对象。

  1. $ ./pickle_ex.py
  2. Monica
  3. 15
  4. Monica
  5. 15

在 Python 教程的这一部分中,我们将处理文件以及 Python 中的标准输入和输出。