文件操作#

文件操作是编程中的常见任务。Python 提供了简单而强大的文件操作功能。

打开和关闭文件#

open() 函数#

# 基本语法:open(file, mode='r', encoding=None)
file = open("data.txt", "r")
content = file.read()
file.close()  # 必须关闭文件

文件模式#

# 'r' - 只读模式(默认)
file = open("data.txt", "r")

# 'w' - 写入模式(覆盖)
file = open("data.txt", "w")

# 'a' - 追加模式
file = open("data.txt", "a")

# 'x' - 创建模式(文件不存在时创建)
file = open("new_file.txt", "x")

# 'b' - 二进制模式
file = open("image.jpg", "rb")

# 't' - 文本模式(默认)
file = open("data.txt", "rt")

# '+' - 读写模式
file = open("data.txt", "r+")  # 读写
file = open("data.txt", "w+")  # 读写(覆盖)

with 语句(推荐)#

使用 with 语句可以自动关闭文件,即使发生异常也会关闭。

# 基本用法
with open("data.txt", "r") as file:
    content = file.read()
# 文件自动关闭

# 多个文件
with open("input.txt", "r") as infile, open("output.txt", "w") as outfile:
    content = infile.read()
    outfile.write(content)

读取文件#

read() 方法#

# 读取整个文件
with open("data.txt", "r") as file:
    content = file.read()
    print(content)

# 读取指定字节数
with open("data.txt", "r") as file:
    content = file.read(100)  # 读取前100个字符

readline() 方法#

# 读取一行
with open("data.txt", "r") as file:
    line = file.readline()
    print(line)

# 读取所有行(逐行)
with open("data.txt", "r") as file:
    while True:
        line = file.readline()
        if not line:
            break
        print(line.strip())  # strip()去除换行符

readlines() 方法#

# 读取所有行,返回列表
with open("data.txt", "r") as file:
    lines = file.readlines()
    for line in lines:
        print(line.strip())

迭代文件对象#

# 直接迭代文件对象(推荐,内存效率高)
with open("data.txt", "r") as file:
    for line in file:
        print(line.strip())

写入文件#

write() 方法#

# 写入字符串
with open("output.txt", "w") as file:
    file.write("Hello, World!\n")
    file.write("这是第二行\n")

# 写入多行
lines = ["第一行\n", "第二行\n", "第三行\n"]
with open("output.txt", "w") as file:
    file.writelines(lines)

追加模式#

# 追加内容到文件末尾
with open("log.txt", "a") as file:
    file.write("新的日志条目\n")

文件位置操作#

with open("data.txt", "r") as file:
    # 获取当前位置
    position = file.tell()
    print(f"当前位置: {position}")
    
    # 移动到指定位置
    file.seek(0)  # 移动到文件开头
    file.seek(10)  # 移动到第10个字节
    file.seek(0, 2)  # 移动到文件末尾(0=起始位置,2=从末尾)
    
    # 读取当前位置之后的内容
    content = file.read()

文件路径操作#

os.path 模块#

import os

# 连接路径
path = os.path.join("folder", "subfolder", "file.txt")

# 获取目录名
dirname = os.path.dirname("/path/to/file.txt")  # /path/to

# 获取文件名
filename = os.path.basename("/path/to/file.txt")  # file.txt

# 分离文件名和扩展名
name, ext = os.path.splitext("file.txt")  # ('file', '.txt')

# 检查路径是否存在
exists = os.path.exists("/path/to/file.txt")

# 检查是否为文件
is_file = os.path.isfile("/path/to/file.txt")

# 检查是否为目录
is_dir = os.path.isdir("/path/to/directory")

# 获取绝对路径
abs_path = os.path.abspath("file.txt")

# 获取当前工作目录
cwd = os.getcwd()

pathlib 模块(Python 3.4+,推荐)#

from pathlib import Path

# 创建Path对象
path = Path("folder/file.txt")

# 路径操作
path.parent      # 父目录
path.name        # 文件名
path.stem        # 文件名(不含扩展名)
path.suffix      # 扩展名
path.exists()    # 是否存在
path.is_file()   # 是否为文件
path.is_dir()    # 是否为目录

# 路径连接
path = Path("folder") / "subfolder" / "file.txt"

# 读取文件
content = path.read_text(encoding="utf-8")

# 写入文件
path.write_text("content", encoding="utf-8")

# 遍历目录
for file in Path(".").iterdir():
    print(file)

CSV 文件处理#

csv 模块#

import csv

# 读取CSV文件
with open("data.csv", "r", encoding="utf-8") as file:
    reader = csv.reader(file)
    for row in reader:
        print(row)

# 使用字典读取(推荐)
with open("data.csv", "r", encoding="utf-8") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row["name"], row["age"])

# 写入CSV文件
with open("output.csv", "w", encoding="utf-8", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(["name", "age", "city"])
    writer.writerow(["Alice", "30", "Beijing"])
    writer.writerow(["Bob", "25", "Shanghai"])

# 使用字典写入
with open("output.csv", "w", encoding="utf-8", newline="") as file:
    fieldnames = ["name", "age", "city"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({"name": "Alice", "age": "30", "city": "Beijing"})

JSON 文件处理#

import json

# 读取JSON文件
with open("data.json", "r", encoding="utf-8") as file:
    data = json.load(file)
    print(data["name"])

# 写入JSON文件
data = {"name": "Alice", "age": 30, "city": "Beijing"}
with open("output.json", "w", encoding="utf-8") as file:
    json.dump(data, file, ensure_ascii=False, indent=2)
    # ensure_ascii=False: 允许非ASCII字符
    # indent=2: 格式化输出,缩进2个空格

上下文管理器(深入)#

自定义上下文管理器#

# 使用类实现
class FileManager:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode
        self.file = None
    
    def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()
        return False  # 返回False表示不抑制异常

# 使用
with FileManager("data.txt", "r") as file:
    content = file.read()

# 使用contextlib模块(更简单)
from contextlib import contextmanager

@contextmanager
def file_manager(filename, mode):
    file = open(filename, mode)
    try:
        yield file
    finally:
        file.close()

# 使用
with file_manager("data.txt", "r") as file:
    content = file.read()

文件操作最佳实践#

1. 总是使用 with 语句#

# 好的做法
with open("data.txt", "r") as file:
    content = file.read()

# 不好的做法
file = open("data.txt", "r")
content = file.read()
file.close()  # 如果发生异常,文件可能不会关闭

2. 指定编码#

# 好的做法
with open("data.txt", "r", encoding="utf-8") as file:
    content = file.read()

# 不好的做法(依赖系统默认编码)
with open("data.txt", "r") as file:
    content = file.read()

3. 处理文件不存在的情况#

from pathlib import Path

file_path = Path("data.txt")
if file_path.exists():
    with open(file_path, "r", encoding="utf-8") as file:
        content = file.read()
else:
    print("文件不存在")

4. 大文件处理#

# 对于大文件,逐行读取而不是一次性读取全部
with open("large_file.txt", "r", encoding="utf-8") as file:
    for line in file:
        process(line)  # 处理每一行

5. 二进制文件#

# 读取二进制文件
with open("image.jpg", "rb") as file:
    data = file.read()

# 写入二进制文件
with open("copy.jpg", "wb") as file:
    file.write(data)

实际应用示例#

def read_config(filename):
    """读取配置文件"""
    config = {}
    with open(filename, "r", encoding="utf-8") as file:
        for line in file:
            line = line.strip()
            if line and not line.startswith("#"):
                key, value = line.split("=", 1)
                config[key.strip()] = value.strip()
    return config

def write_log(message, logfile="app.log"):
    """写入日志"""
    from datetime import datetime
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open(logfile, "a", encoding="utf-8") as file:
        file.write(f"[{timestamp}] {message}\n")

下一步#

掌握了文件操作后,可以学习:

  1. 高级特性 - 学习生成器、迭代器等高级特性
  2. 常用内置函数 - 学习常用的内置函数