当前位置:首页>python>Python零基础入门(六):文件操作

Python零基础入门(六):文件操作

  • 2026-09-10 16:11:02
Python零基础入门(六):文件操作

Python零基础入门(六):文件操作

前言

前五篇我们完成了环境搭建与数据类型、运算符与条件判断、面向对象编程基础、模块与包导入和异常处理。你已经能让程序"算"、能"想"、能"组织"、能"容错"——但程序运行的结果总是转瞬即逝,关闭终端就没了。

如何让数据持久化?如何读取配置文件?如何生成报告?如何处理日志?

这就是本篇要解决的核心问题:文件操作。文件操作让你的程序能与外部世界交换数据——读取文本、保存结果、处理日志、导出报表。


一、文件操作基础

Python 内置了强大的文件操作功能,无需额外安装模块即可完成绝大多数文件读写任务。

1.1 打开文件:open() 函数

# 基本语法file = open("example.txt", "r", encoding="utf-8")# 参数说明:# - 第一个参数:文件路径(相对路径或绝对路径)# - 第二个参数:打开模式(见下表)# - encoding:编码格式(处理文本文件时推荐指定)

打开模式一览:

模式
说明
文件不存在时
文件存在时
'r'
只读(默认)
报错
正常读取
'w'
写入
创建新文件
清空后写入
'a'
追加
创建新文件
在末尾追加
'x'
排他创建
创建新文件
报错
'b'
二进制模式
可与其他模式组合
—
't'
文本模式(默认)
可与其他模式组合
—
'+'
读写模式
可与其他模式组合
—

常见组合:

open("file.txt", "r")      # 只读文本open("file.txt", "w")      # 写入文本(清空原内容)open("file.txt", "a")      # 追加文本open("file.bin", "rb")     # 只读二进制open("file.bin", "wb")     # 写入二进制open("file.txt", "r+")     # 读写文本

1.2 读取文件内容

# 方法一:read() —— 读取全部内容file = open("poem.txt", "r", encoding="utf-8")content = file.read()      # 返回整个文件内容的字符串print(content)file.close()               # 记得关闭文件!# 方法二:readline() —— 逐行读取file = open("poem.txt", "r", encoding="utf-8")line1 = file.readline()    # 读取第一行(包含换行符 \n)line2 = file.readline()    # 读取第二行print(line1, line2)file.close()# 方法三:readlines() —— 读取所有行到列表file = open("poem.txt", "r", encoding="utf-8")lines = file.readlines()   # 返回列表,每个元素是一行for line in lines:    print(line.strip())    # strip() 去除换行符file.close()# 方法四:迭代读取(推荐,内存友好)file = open("poem.txt", "r", encoding="utf-8")for line in file:          # 文件对象本身可迭代    print(line.strip())file.close()

注意:readline() 和 readlines() 读取的行末尾包含换行符 \n,通常需要用 strip() 或 rstrip() 去除。

1.3 写入文件

# 写入字符串file = open("output.txt", "w", encoding="utf-8")file.write("第一行内容\n")    # write() 不会自动添加换行符file.write("第二行内容\n")file.close()# 写入多行(writelines)lines = ["苹果\n", "香蕉\n", "橘子\n"]file = open("fruits.txt", "w", encoding="utf-8")file.writelines(lines)       # 不会自动添加换行符,需要自己处理file.close()# 追加模式from datetime import datetimefile = open("log.txt", "a", encoding="utf-8")file.write(f"[{datetime.now()}] 用户登录\n")file.close()

1.4 文件指针操作

文件有一个"指针",记录当前读写位置:

file = open("example.txt", "r", encoding="utf-8")# tell() —— 获取当前位置print(file.tell())         # 0(开头)# read(n) —— 读取 n 个字符data = file.read(5)print(file.tell())         # 5(移动了 5 个字符)# seek(offset, whence) —— 移动指针# whence: 0=开头(默认),1=当前位置,2=末尾file.seek(0)               # 回到开头print(file.tell())         # 0file.close()

注意:seek() 在文本模式下,whence 参数只能是 0(只有二进制模式支持 1 和 2)。


二、上下文管理器:with 语句

手动调用 file.close() 容易遗忘,更糟糕的是如果读写过程中发生异常,文件可能不会被正确关闭。with 语句(上下文管理器)完美解决了这个问题:

# 传统写法(有风险)file = open("data.txt", "r")content = file.read()# 如果这里发生异常,file.close() 不会执行!file.close()# with 写法(安全)with open("data.txt", "r", encoding="utf-8") as file:    content = file.read()# 退出 with 块后,文件自动关闭(即使发生异常)

2.1 with 语句的优势

  1. 1. 自动关闭文件:离开 with 块后自动调用 close()
  2. 2. 异常安全:即使发生异常也能正确关闭文件
  3. 3. 代码更简洁:无需显式调用 close()

2.2 推荐用法

始终使用 with 语句操作文件:

# 读取with open("input.txt", "r", encoding="utf-8") as f:    for line in f:        print(line.strip())# 写入with open("output.txt", "w", encoding="utf-8") as f:    f.write("Hello, Python!\n")    f.write("文件操作很简单\n")# 复制文件with open("source.txt", "r", encoding="utf-8") as src:    content = src.read()with open("dest.txt", "w", encoding="utf-8") as dst:    dst.write(content)

2.3 同时打开多个文件

Python 3.10+ 支持在同一个 with 语句中打开多个文件:

# 复制文件(同时打开源和目标)with open("source.txt", "r", encoding="utf-8") as src, \     open("dest.txt", "w", encoding="utf-8") as dst:    for line in src:        dst.write(line)

三、文件和目录操作:os 模块

Python 的 os 模块提供了丰富的文件和目录操作功能。

3.1 路径操作

import os# 获取当前工作目录cwd = os.getcwd()print(cwd)# 路径拼接(推荐,跨平台兼容)path = os.path.join("data", "files", "test.txt")print(path)  # data/files/test.txt(Linux/Mac)             # data\files\test.txt(Windows)# 获取文件名和目录print(os.path.basename("/home/user/test.txt"))  # test.txtprint(os.path.dirname("/home/user/test.txt"))   # /home/user# 分离扩展名name, ext = os.path.splitext("report.pdf")print(name)  # reportprint(ext)   # .pdf# 判断路径是否存在print(os.path.exists("/tmp/test.txt"))  # True 或 False# 判断是文件还是目录print(os.path.isfile("/tmp/test.txt"))  # Trueprint(os.path.isdir("/tmp"))            # True# 获取文件大小(字节)size = os.path.getsize("test.txt")print(f"文件大小:{size} 字节")# 获取绝对路径print(os.path.abspath("."))  # 当前目录的绝对路径

3.2 目录操作

import os# 创建目录os.mkdir("new_folder")           # 创建单级目录os.makedirs("a/b/c", exist_ok=True)  # 创建多级目录(exist_ok=True 避免已存在时报错)# 列出目录内容files = os.listdir(".")          # 列出当前目录所有文件和文件夹print(files)# 遍历目录树for root, dirs, files in os.walk("my_project"):    print(f"当前目录:{root}")    print(f"  子目录:{dirs}")    print(f"  文件:{files}")# 删除目录os.rmdir("empty_folder")         # 删除空目录import shutilshutil.rmtree("folder_to_delete")  # 删除非空目录(谨慎使用!)

3.3 文件操作

import osimport shutil# 重命名/移动文件os.rename("old.txt", "new.txt")os.rename("file.txt", "archive/file.txt")  # 移动# 复制文件shutil.copy("source.txt", "dest.txt")           # 复制文件shutil.copy2("source.txt", "dest.txt")          # 复制文件(保留元数据)shutil.copytree("src_folder", "dest_folder")    # 复制整个目录# 删除文件os.remove("file.txt")os.unlink("file.txt")  # 和 remove() 等价

四、实用文件处理技巧

4.1 统计文件信息(类似 wc 命令)

def count_file(filename):    """统计文件的行数、单词数和字符数"""    lines = 0    words = 0    chars = 0    with open(filename, "r", encoding="utf-8") as f:        for line in f:            lines += 1            words += len(line.split())            chars += len(line)    return lines, words, chars# 使用lines, words, chars = count_file("example.txt")print(f"行数:{lines},单词数:{words},字符数:{chars}")

4.2 安全写入(避免覆盖已有文件)

import osdef safe_write(filename, content):    """安全写入文件,如果文件已存在则添加数字后缀"""    if not os.path.exists(filename):        with open(filename, "w", encoding="utf-8") as f:            f.write(content)        return filename    # 文件已存在,生成新文件名    name, ext = os.path.splitext(filename)    counter = 1    while os.path.exists(f"{name}_{counter}{ext}"):        counter += 1    new_filename = f"{name}_{counter}{ext}"    with open(new_filename, "w", encoding="utf-8") as f:        f.write(content)    return new_filename# 使用result = safe_write("report.txt", "这是报告内容")print(f"文件已保存:{result}")

4.3 读取配置文件

def read_config(filename):    """读取 key=value 格式的配置文件"""    config = {}    try:        with open(filename, "r", encoding="utf-8") as f:            for line_num, line in enumerate(f, 1):                line = line.strip()                # 跳过空行和注释                if not line or line.startswith("#"):                    continue                # 解析 key=value                if "=" not in line:                    print(f"警告:第 {line_num} 行格式错误,已跳过")                    continue                key, value = line.split("=", 1)                config[key.strip()] = value.strip()    except FileNotFoundError:        print(f"配置文件不存在:{filename}")    except Exception as e:        print(f"读取配置文件失败:{e}")    return config# 使用config = read_config("app.conf")print(config)

4.4 批量重命名文件

import osdef batch_rename(folder, prefix="file", start=1):    """批量重命名文件夹中的文件"""    files = sorted(os.listdir(folder))    renamed = []    for i, filename in enumerate(files, start):        # 获取扩展名        _, ext = os.path.splitext(filename)        # 新文件名        new_name = f"{prefix}_{i:03d}{ext}"        # 完整路径        old_path = os.path.join(folder, filename)        new_path = os.path.join(folder, new_name)        # 重命名        os.rename(old_path, new_path)        renamed.append((filename, new_name))        print(f"重命名:{filename} → {new_name}")    return renamed# 使用# batch_rename("photos", prefix="photo", start=1)

4.5 文件备份工具

import osimport shutilfrom datetime import datetimedef backup_files(source_dir, backup_dir, extensions=None):    """    备份指定目录下的文件    Args:        source_dir: 源目录        backup_dir: 备份目录        extensions: 要备份的文件扩展名列表,如 [".txt", ".py"],None 表示全部    """    # 创建备份目录    os.makedirs(backup_dir, exist_ok=True)    # 记录备份信息    backup_log = []    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")    # 遍历源目录    for root, dirs, files in os.walk(source_dir):        for filename in files:            # 检查扩展名            if extensions:                _, ext = os.path.splitext(filename)                if ext.lower() not in extensions:                    continue            # 源文件路径            src_path = os.path.join(root, filename)            # 保持目录结构            rel_path = os.path.relpath(src_path, source_dir)            dst_path = os.path.join(backup_dir, rel_path)            # 创建目标目录            os.makedirs(os.path.dirname(dst_path), exist_ok=True)            # 复制文件            shutil.copy2(src_path, dst_path)            backup_log.append(rel_path)            print(f"备份:{rel_path}")    # 写入备份日志    log_path = os.path.join(backup_dir, "backup_log.txt")    with open(log_path, "w", encoding="utf-8") as f:        f.write(f"备份时间:{timestamp}\n")        f.write(f"源目录:{source_dir}\n")        f.write(f"备份目录:{backup_dir}\n")        f.write(f"文件数量:{len(backup_log)}\n")        f.write("\n备份文件列表:\n")        for file in backup_log:            f.write(f"  - {file}\n")    print(f"\n备份完成!共 {len(backup_log)} 个文件")    print(f"日志已保存:{log_path}")# 使用# backup_files("project", "backup", extensions=[".txt", ".py", ".json"])

五、综合实战:日志文件处理器

让我们结合文件操作和异常处理,实现一个实用的日志处理器:

import osfrom datetime import datetimeclass Logger:    """简单的日志记录器"""    def __init__(self, log_file="app.log"):        self.log_file = log_file        # 确保日志目录存在        log_dir = os.path.dirname(log_file)        if log_dir and not os.path.exists(log_dir):            os.makedirs(log_dir, exist_ok=True)    def _write_log(self, level, message):        """写入日志(内部方法)"""        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")        log_entry = f"[{timestamp}] [{level}] {message}\n"        try:            with open(self.log_file, "a", encoding="utf-8") as f:                f.write(log_entry)        except PermissionError:            print(f"警告:没有权限写入日志文件 {self.log_file}")        except Exception as e:            print(f"警告:写入日志失败 - {e}")    def info(self, message):        """记录信息级别日志"""        self._write_log("INFO", message)    def error(self, message):        """记录错误级别日志"""        self._write_log("ERROR", message)    def warning(self, message):        """记录警告级别日志"""        self._write_log("WARNING", message)    def read_logs(self, n=10):        """读取最后 n 条日志"""        try:            with open(self.log_file, "r", encoding="utf-8") as f:                lines = f.readlines()                return lines[-n:] if len(lines) >= n else lines        except FileNotFoundError:            return []        except Exception as e:            print(f"读取日志失败:{e}")            return []    def clear_logs(self):        """清空日志文件"""        try:            with open(self.log_file, "w", encoding="utf-8") as f:                f.write("")            return True        except Exception as e:            print(f"清空日志失败:{e}")            return False# 使用示例if __name__ == "__main__":    logger = Logger("logs/application.log")    logger.info("应用程序启动")    logger.info("用户登录:张三")    logger.warning("磁盘空间不足")    logger.error("数据库连接失败")    print("\n最近的日志:")    for log in logger.read_logs(5):        print(log.strip())

这个例子展示了:

  1. 1. 文件操作:读写日志文件、创建目录
  2. 2. 异常处理:捕获文件权限、文件不存在等异常
  3. 3. 类的使用:封装日志功能
  4. 4. 上下文管理器:使用 with 语句安全操作文件

六、动手练习

  1. 1. 写一个程序,读取一个文本文件,统计其中的行数、单词数和字符数(类似 wc 命令)。
  2. 2. 创建一个函数 safe_write(filename, content),写入文件时如果文件已存在,自动在文件名后添加数字后缀(如 file_1.txt、file_2.txt)。
  3. 3. 实现一个配置文件读取器,支持读取简单的 key=value 格式的配置文件,处理文件不存在、格式错误等异常。
  4. 4. 写一个文件备份工具,给定源目录,将所有 .txt 文件复制到备份目录,并在备份目录中创建一个 backup_log.txt 记录备份时间、文件列表等信息。
  5. 5. 实现一个简单的"记事本"程序,支持以下功能:
    • • 新建文件
    • • 打开文件
    • • 保存文件
    • • 另存为
    • • 显示文件内容

七、小结

本篇我们系统学习了 Python 的文件操作:

核心语法

  • • open() 函数:打开文件,指定模式和编码
  • • 读写方法:read()、readline()、readlines()、write()、writelines()
  • • with 语句:自动管理文件关闭,异常安全

os 模块

  • • 路径操作:join()、basename()、dirname()、splitext()、exists()
  • • 目录操作:mkdir()、makedirs()、listdir()、walk()
  • • 文件操作:rename()、remove()
  • • shutil 模块:copy()、copy2()、copytree()、rmtree()

最佳实践

  • • 始终使用 with 语句:自动关闭文件,异常安全
  • • 指定编码格式:避免跨平台编码问题
  • • 异常处理:捕获文件不存在、权限不足等异常

掌握文件操作,你的程序就能读写数据、处理配置、生成报告、记录日志。这是编写实用程序的基础技能。

至此,Python 零基础入门系列的六篇文章全部完成。你已经掌握了 Python 编程的核心基础知识:

  1. 1. 环境搭建与数据类型
  2. 2. 运算符与条件判断
  3. 3. 面向对象编程基础
  4. 4. 模块与包导入
  5. 5. 异常处理
  6. 6. 文件操作

下一步,建议你多动手实践,尝试完成每篇的练习题,或者找一些小项目练手。编程是一项实践技能,只有不断练习才能真正掌握。

祝你学习愉快,Python 之路越走越远!


本文首发于微信公众号「羽您码上聊」,欢迎关注获取更多技术内容。

最新文章

随机文章