Python 零基础教程

Python 文件读取

在深入学习如何读取数据之前,我们先简要回顾一下如何打开文件,这是至关重要的第一步。在 Python 中,你需要使用 open() 函数来打开文件。回顾上一章的内容,基本语法是 open(filename, mode)mode 参数指定了你打开文件的目的(读取、写入、追加等)。在本章中,我们将主要关注读取模式('r')。

当你使用完文件后,使用 close() 方法将其关闭是非常重要的。这会释放系统资源并防止潜在的问题。虽然 Python 拥有垃圾回收机制,会在文件不再被引用时自动关闭它们,但依赖这种机制并不符合最佳实践。

处理文件更安全、更具 Python 风格(Pythonic)的方法是使用 with 语句。with 语句会自动负责关闭文件,即使在处理过程中发生了错误也是如此。这能确保文件始终被正确关闭。

# 使用 'with' 语句打开文件进行读取的示例
filename = "my_file.txt" # 假设该文件目前存在,我们稍后会创建它。

try:
    with open(filename, 'r') as file:
        # 在此处进行文件操作
        pass # 在这个例子中我们还没做任何操作,只是想展示代码的结构。
    # 在 'with' 代码块结束后,文件会自动关闭

except FileNotFoundError:
    print(f"错误:找不到文件 '{filename}'。")
except Exception as e:
    print(f"发生了一个错误:{e}")

1. 逐行读取文件数据

从文件中读取数据的一种常见方式是逐行读取。当你处理可能无法完全装入内存的大文件时,这种方法特别有用。Python 提供了几种逐行读取文件的方法:

1.1 使用 for 循环

逐行读取文件最简单、最符合 Python 风格的方法是直接对文件对象使用 for 循环。当你以这种方式遍历文件对象时,Python 会自动一次读取一行。

filename = "my_file.txt"

try:
    with open(filename, 'r') as file:
        for line in file:
            # 处理每一行
            print(line.strip())  # 移除行首和行尾的空白字符
            
except FileNotFoundError:
    print(f"错误:找不到文件 '{filename}'。")
except Exception as e:
    print(f"发生了一个错误:{e}")

在这个例子中:

  • 我们使用 with 语句以读取模式('r')打开了文件 "my_file.txt"
  • for line in file: 循环遍历文件中的每一行。
  • 在循环内部,line 代表文件中的单行文本,包含末尾的换行符(\n)。
  • line.strip() 会移除任何开头或结尾的空白字符(包括换行符),使输出结果更加整洁。
  • 我们加入了 try...except 代码块来处理可能发生的错误,比如文件未找到。

示例:
假设 my_file.txt 包含以下内容:

This is the first line.
This is the second line.
And this is the third.

上述代码的输出结果将会是:

This is the first line.
This is the second line.
And this is the third.

1.2 使用 readline()

另一种逐行读取文件的方法是使用 readline() 方法。此方法从文件中读取单行内容并将其作为字符串返回。随后每次调用 readline() 都会返回文件中的下一行。当到达文件末尾时,readline() 会返回一个空字符串("")。

filename = "my_file.txt"

try:
    with open(filename, 'r') as file:
        line = file.readline()
        while line:
            print(line.strip())
            line = file.readline()
            
except FileNotFoundError:
    print(f"错误:找不到文件 '{filename}'。")
except Exception as e:
    print(f"发生了一个错误:{e}")

在这个例子中:

  • 我们以读取模式打开文件 "my_file.txt"
  • line = file.readline() 读取文件的第一行。
  • 只要 readline() 返回一个非空字符串(意味着我们还没到达文件末尾),while line: 循环就会继续执行。
  • 在循环内部,我们打印该行内容(在移除空白字符后),然后使用 line = file.readline() 读取下一行。
  • 我们加入了 try...except 代码块来处理潜在的错误。

这种方法比使用 for 循环稍微繁琐一些,但它为你提供了对读取过程更明确的控制。

注意事项:空行 如果文件中的某一行是真正的空行(仅包含一个换行符),readline() 将返回 \n。此时 strip() 方法会将其移除,导致打印出一个空字符串。如果你需要区分空行和文件末尾,你需要在调用 strip() 之前检查 line 的值。

2. 读取整个文件

有时候,你需要将文件的全部内容读取到一个单一的字符串中。这适用于内存使用量不是问题的小型文件。Python 为此提供了 read() 方法。

2.1 使用 read()

read() 方法从当前文件指针位置读取文件的全部内容,并将其作为一个字符串返回。如果你在读取完整个文件后再次调用 read(),它将返回一个空字符串。

filename = "my_file.txt"

try:
    with open(filename, 'r') as file:
        content = file.read()
        print(content)
        
except FileNotFoundError:
    print(f"错误:找不到文件 '{filename}'。")
except Exception as e:
    print(f"发生了一个错误:{e}")

在这个例子中:

  • 我们以读取模式打开文件 "my_file.txt"
  • content = file.read() 将文件的全部内容作为一个字符串读取到 content 变量中。
  • 然后我们打印文件的全部内容。
  • 我们加入了 try...except 代码块来处理潜在的错误。

示例:
如果 my_file.txt 包含:

This is the first line.
This is the second line.
And this is the third.

上述代码的输出结果将会是:

This is the first line.
This is the second line.
And this is the third.

2.2 读取指定数量的字符

read() 方法还可以接受一个可选参数:要读取的字符数。如果你想分块读取文件,这会非常有用。

filename = "my_file.txt"

try:
    with open(filename, 'r') as file:
        chunk1 = file.read(10)  # 读取前 10 个字符
        print("区块 1:", chunk1)
        
        chunk2 = file.read(15)  # 读取接下来的 15 个字符
        print("区块 2:", chunk2)
        
except FileNotFoundError:
    print(f"错误:找不到文件 '{filename}'。")
except Exception as e:
    print(f"发生了一个错误:{e}")

在这个例子中,第一次调用 read(10) 读取了文件的前 10 个字符。第二次调用 read(15) 从第一次调用停止的地方开始,读取了接下来的 15 个字符。

如果 my_file.txt 的内容是 "This is some text in the file.",那么输出将会是:

区块 1: This is so
区块 2: me text in the

3. 读取方法对比

方法读取方式内存消耗最佳使用场景
for 循环每次一行高效大文件,需要逐行处理
readline()每次一行高效大文件,需要对读取行进行显式控制
read()整个文件可能很高中小型文件,简单的整体处理