进阶输入输出 (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 是如何查找变量的。