Kodokon kodokon.com

文件与模块:with、import、代码组织

用 with 干净地读写文件,用 JSON 交换数据,并把代码组织成可导入的模块。

10 分钟 · 3 题

在 Kodokon 中打开本课

读写文件是真实程序的家常便饭:导出、日志、配置。with 关键字打开文件并保证它会被关闭,即便代码块中途发生错误也一样。这是打开文件唯一专业的方式:没有它,一个被遗忘的 close() 可能会损坏数据,或耗尽系统资源。

PYTHON
lines = ["alpha", "beta", "gamma"]

with open("notes.txt", "w", encoding="utf-8") as f:
    for line in lines:
        f.write(line + "\n")

with open("notes.txt", encoding="utf-8") as f:
    content = f.read()

print(content)
'w' 模式以覆盖内容的方式写入;不指定模式时则是读取。

对于结构化数据,别自己发明格式:标准库中的 json 模块能把字典和列表转换成文本,也能再转换回来。它是程序、API 和配置文件之间通用的交换格式。

PYTHON
import json

config = {"debug": True, "retries": 3}

with open("config.json", "w", encoding="utf-8") as f:
    json.dump(config, f, indent=2)

with open("config.json", encoding="utf-8") as f:
    loaded = json.load(f)

print(loaded["retries"])  # 3
json.dump 写出结构,json.load 把它重建回来。

模块其实就是一个 .py 文件:import billing 会加载 billing.py,并且只运行它的内容一次。请按职责组织你的代码 - 一个模块负责计费,另一个负责存储 - 并把 import 语句放在文件顶部。if __name__ == "__main__" 这个判断区分了两种情况:直接运行时,文件会执行这个代码块;被导入时,则会忽略它。

PYTHON
def compute_total(prices):
    return round(sum(prices), 2)

def main():
    print(compute_total([9.99, 4.5, 20.0]))

if __name__ == "__main__":
    main()
billing.py 的内容:可以在任何地方导入,也能直接运行。
BASH
python billing.py
这样运行时,文件会执行 main();被导入时,它什么也不做。

知识检测

确认你已牢记本课的重点内容。

  1. 相比单独使用 open(),with open(...) 的主要优势是什么?
    • 文件会被自动关闭,即使发生错误也一样
    • 读取文件的速度更快
    • 无论什么模式,文件不存在时都会被创建
  2. "w" 模式和 "a" 模式有什么区别?
    • "w" 覆盖已有内容,"a" 追加到末尾
    • "w" 写入文本,"a" 写入二进制
    • "w" 会创建文件,"a" 在文件不存在时会失败
  3. if __name__ == "__main__" 这个判断有什么用?
    • 用来检查文件是否真的叫 main.py
    • 只在文件被直接启动时才运行某个代码块
    • 阻止其他文件导入这个模块