跳转至

进阶输入输出 (Advanced I/O)

在基础部分,我们学习了简单的 input()print() 和基础的文件读写。在进阶开发中,我们需要处理更复杂的数据格式(如 JSON、CSV),更优雅地管理文件路径,以及构建能够接收命令行参数的脚本工具。

1. 现代化路径操作:pathlib

在 Python 3.4 之前,我们主要使用 os.path 模块处理文件路径,这通常涉及大量的字符串拼接,容易出错且不跨平台。pathlib 模块提供了一种面向对象的方式来处理文件系统路径。

为什么选择 pathlib

  • 面向对象:路径不再是字符串,而是对象。
  • 跨平台:自动处理 Windows (\) 和 Linux (/) 的路径分隔符差异。
  • 链式调用:代码更流畅。

常用操作示例

from pathlib import Path

# 获取当前脚本所在目录
current_dir = Path(__file__).parent
print(f"当前目录: {current_dir}")

# 路径拼接 (使用 / 操作符)
data_file = current_dir / "data" / "users.json"
print(f"数据文件路径: {data_file}")

# 检查文件/目录是否存在
if not data_file.exists():
    print("文件不存在,创建一个!")
    # 创建目录 (parents=True 表示如果父目录不存在也一并创建)
    data_file.parent.mkdir(parents=True, exist_ok=True) 
    # 创建空文件
    data_file.touch()

# 获取文件名和后缀
print(f"文件名: {data_file.name}") # users.json
print(f"后缀名: {data_file.suffix}") # .json
print(f"主文件名: {data_file.stem}") # users

2. 数据序列化:JSON

JSON (JavaScript Object Notation) 是目前互联网上最通用的轻量级数据交换格式。Python 的 json 模块可以轻松地在 Python 对象(字典、列表)和 JSON 字符串之间转换。

序列化 (Dump) 与 反序列化 (Load)

  • json.dumps(): 将 Python 对象转换为 JSON 字符串
  • json.loads(): 将 JSON 字符串转换为 Python 对象。
  • json.dump(): 将 Python 对象写入 JSON 文件
  • json.load(): 从 JSON 文件读取 Python 对象。
import json

data = {
    "name": "GitHub Copilot",
    "version": 1.0,
    "features": ["code", "chat", "debug"],
    "is_active": True
}

# 1. 写入文件
# ensure_ascii=False 保证中文字符能正常显示,而不是 \uXXXX
# indent=4 用于美化输出,方便阅读
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=4)

# 2. 从文件读取
with open("data.json", "r", encoding="utf-8") as f:
    loaded_data = json.load(f)
    print(loaded_data["name"]) # 输出: GitHub Copilot

3. CSV 文件处理

CSV (Comma-Separated Values) 是表格数据的常用存储格式。Python 的 csv 模块提供了读写 CSV 的功能。

import csv

# 写入 CSV
headers = ['Name', 'Age', 'City']
rows = [
    ['Alice', 25, 'New York'],
    ['Bob', 30, 'San Francisco'],
    ['Charlie', 35, 'London']
]

with open('people.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(headers)
    writer.writerows(rows)

# 读取 CSV (以字典形式读取,更直观)
with open('people.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"{row['Name']} is {row['Age']} years old.")

Pandas 更强大

对于复杂的数据分析任务,标准的 csv 模块可能显得繁琐。通常我们会使用第三方库 Pandas (pd.read_csv, df.to_csv) 来处理 CSV 数据,效率极高。

4. 命令行参数:argparse

当你编写一个 Python 脚本工具时,通常希望通过命令行传递参数(如文件路径、配置选项等)。argparse 是标准库中推荐的命令行解析模块。

假设文件名为 cli_tool.py

import argparse

def main():
    # 1. 创建解析器
    parser = argparse.ArgumentParser(description="这是一个示例命令行工具")

    # 2. 添加参数
    # 位置参数 (必须提供)
    parser.add_argument("filename", help="要处理的文件名")
    # 可选参数 (以 - 或 -- 开头)
    parser.add_argument("-n", "--number", type=int, default=1, help="重复次数")
    parser.add_argument("-v", "--verbose", action="store_true", help="显示详细日志")

    # 3. 解析参数
    args = parser.parse_args()

    # 4. 使用参数
    if args.verbose:
        print(f"正在处理文件: {args.filename},重复 {args.number} 次...")

    for _ in range(args.number):
        print(f"Processing {args.filename}")

if __name__ == "__main__":
    main()

在终端运行:

python cli_tool.py data.txt -n 3 -v

总结

  • 使用 pathlib 替代 os.path 进行文件路径操作。
  • 使用 json 模块处理 API 数据和配置文件。
  • 使用 csv 模块处理简单的表格数据,复杂数据交给 pandas
  • 使用 argparse 为脚本编写专业的命令行接口。

下一步

学习完如何与外界交互,我们再次把视角拉回 Python 语言本身。在编写函数和类时,经常遇到“变量找不到”或“变量被意外修改”的情况。这就需要深入理解 Python 是如何查找变量的。

👉 前往下一章:命名空间与作用域 (Namespaces and Scopes)