返回专题首页

Python 专题

与外部世界交互:文件读写、路径处理与编码问题

只要程序不再停留在内存里的小练习,就一定要和外部世界打交道。读配置文件、写日志、处理 CSV、拼接路径、跨平台运行,这些看起来琐碎的操作,往往才是日常开发中最常见的“真问题”。

Python 专题第 19 篇 / 39 篇4 分钟

只要程序不再停留在内存里的小练习,就一定要和外部世界打交道。读配置文件、写日志、处理 CSV、拼接路径、跨平台运行,这些看起来琐碎的操作,往往才是日常开发中最常见的“真问题”。

这一节我们会把文件 I/O、路径处理、编码和常见数据交换格式放到一起讲清楚,帮助你建立一套更稳妥的外部交互习惯,而不是每次遇到乱码或路径问题再临时搜索。

文本文件与二进制文件

文件并不都是一回事。最常见的区别,是文本文件和二进制文件。

文本文件强调“按字符解释”,比如 .txt.json.csv、代码文件。二进制文件强调“按字节处理”,比如图片、音频、压缩包、Excel 文件。

所以文件读写的第一步,不是记住 open() 参数,而是先问清楚:我面对的到底是文本数据,还是原始字节流。

在 Python 里,这通常会体现为:

  • 文本模式:"r""w"
  • 二进制模式:"rb""wb"

一旦这个判断错了,后面就很容易出现乱码、解析失败或写入损坏的问题。

文件读写的常见方式

一次性读取

如果文件很小,一次性读取最直接:

with open("config.json", "r", encoding="utf-8") as file:
    content = file.read()

它适合配置文件、短文本模板、小型数据样本这类体积可控的场景。

但这里的前提是文件规模确实可控。不要因为写法方便,就把几百兆日志文件也一把读进内存。

按行读取

对于日志、大文本或流式处理场景,按行读取会更稳妥:

with open("app.log", "r", encoding="utf-8") as file:
    for line in file:
        print(line.strip())

这种写法的好处在于:

  • 内存占用更稳定;
  • 更适合边读边处理;
  • 更容易和生成器、过滤逻辑组合。

所以文件读取方式的选择,本质上是在“简单直接”和“资源友好”之间做判断。

编码问题为什么总是绕不过去?

很多文件问题,表面上像是“读不出来”,本质上其实是编码不一致。

文本文件在磁盘上本质还是字节。只有当你用某种字符编码去解释它时,它才会变成可读文本。

最常见、也最推荐的做法,是尽量统一使用 utf-8

with open("demo.txt", "r", encoding="utf-8") as file:
    ...

如果你不显式写编码,程序可能会依赖系统默认编码,这就容易导致“本机可以、换台机器就不行”的问题。

所以对于文本文件处理,一个非常值得坚持的习惯是:只要你知道是文本,就尽量显式写上编码。

pathlib:现代路径处理方式

过去很多人习惯用字符串拼路径,但这会带来不少跨平台问题,比如分隔符差异、拼接可读性差、路径操作分散。

pathlib 提供了一种更现代的方式:

from pathlib import Path

base_dir = Path("data")
file_path = base_dir / "users.json"

这种写法的好处很明显:

  • 路径拼接更自然;
  • API 更统一;
  • 代码语义更清楚。

而且 Path 不只是拼路径,它还封装了很多常见能力,比如:

  • 判断文件是否存在;
  • 创建目录;
  • 读取文本和写入文本;
  • 获取后缀、父目录和绝对路径。

所以在现代 Python 项目里,pathlib 通常比手动拼字符串更值得优先使用。

JSON、CSV 与简单数据交换

真实项目里,与外部世界交互时最常见的数据格式通常不是“任意文本”,而是带结构的格式。

JSON 很适合表示对象和嵌套结构:

import json

with open("user.json", "r", encoding="utf-8") as file:
    data = json.load(file)

CSV 则更适合二维表格型数据:

import csv

with open("users.csv", "r", encoding="utf-8") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row)

这里要建立的心智是:文件格式不只是“扩展名不同”,而是对应不同的数据结构和读写方式。

所以文件处理真正成熟的姿势,不是把所有东西都先读成字符串再手动拆,而是优先找到与格式匹配的标准工具。

总结与预告

这一节我们把 Python 程序离开内存之后最常见的几类交互整理清楚了,包括文件 I/O、路径拼接、编码问题以及基础数据交换格式。它们虽然不炫,但几乎会在所有项目里反复出现。

下一节我们会把注意力转向标准库工具箱,先从容器增强、迭代处理和函数工具这三类高频模块开始。