当前位置: 代码网 > it编程>前端脚本>Python > Python如何使用os模块遍历目录下的所有文件

Python如何使用os模块遍历目录下的所有文件

2026年08月17日 Python 我要评论
在日常的编程工作中,我们经常需要处理文件和目录的操作。无论是数据清洗、日志分析、批量重命名,还是自动化脚本编写,遍历目录中的所有文件都是一个非常基础但又极其重要的技能。而 os 模块作为 python

在日常的编程工作中,我们经常需要处理文件和目录的操作。无论是数据清洗、日志分析、批量重命名,还是自动化脚本编写,遍历目录中的所有文件都是一个非常基础但又极其重要的技能。而 os 模块作为 python 标准库中与操作系统交互的核心模块,提供了强大的功能来完成这项任务。

今天,我们就来深入探讨如何使用 os 模块高效、安全地遍历目录下的所有文件,包括子目录、隐藏文件、权限控制等高级场景,并通过实际代码示例带你从入门到精通。

什么是 os 模块?

os 模块是 python 的标准库之一,它提供了一种方式来使用操作系统的功能,如文件和目录操作、环境变量管理、进程管理等。它在不同平台上(windows、linux、macos)都能保持一致的行为,是跨平台开发的理想选择。

提示:os 模块不依赖外部库,开箱即用,非常适合做系统级操作。

基础:使用 os.listdir() 遍历目录

最简单的遍历方式是使用 os.listdir() 函数。它返回指定目录下所有文件和子目录的名称列表。

import os

# 指定要遍历的目录路径
directory = "/path/to/your/folder"

# 获取目录内容
files_and_dirs = os.listdir(directory)

print("目录内容:")
for item in files_and_dirs:
    print(f"📁 {item}")

注意

  • os.listdir() 只列出当前目录的内容,不会递归进入子目录。
  • 它返回的是字符串列表,包含文件名和文件夹名。
  • 如果路径不存在或没有访问权限,会抛出 filenotfounderrorpermissionerror

递归遍历:os.walk() —— 真正的“全遍历”工具

如果你需要遍历一个目录及其所有子目录中的文件,os.walk() 是你的首选。它是一个生成器函数,逐层返回 (dirpath, dirnames, filenames) 三元组。

示例代码:完整递归遍历

import os

def traverse_directory(root_dir):
    print(f"🔍 正在遍历目录: {root_dir}")
    for dirpath, dirnames, filenames in os.walk(root_dir):
        # 打印当前目录路径
        print(f"📂 当前目录: {dirpath}")

        # 打印所有文件
        for filename in filenames:
            file_path = os.path.join(dirpath, filename)
            print(f"📄 文件: {file_path}")

        # 打印所有子目录(可选)
        for dirname in dirnames:
            dir_full_path = os.path.join(dirpath, dirname)
            print(f"📁 子目录: {dir_full_path}")

# 调用函数
traverse_directory("/users/yourname/documents")

输出示例(简化)

🔍 正在遍历目录: /users/yourname/documents
📂 当前目录: /users/yourname/documents
📄 文件: /users/yourname/documents/report.pdf
📄 文件: /users/yourname/documents/config.json
📁 子目录: /users/yourname/documents/backup
📂 当前目录: /users/yourname/documents/backup
📄 文件: /users/yourname/documents/backup/old_data.zip

os.walk() 的内部机制:一个动态图解

让我们用 mermaid 画一张流程图,展示 os.walk() 如何递归遍历目录结构。

这个图展示了 os.walk() 的递归逻辑:先深入到底层,再逐步回溯处理每一层的文件

处理常见异常:权限与路径错误

在真实环境中,你可能遇到以下问题:

  • 目录不存在
  • 无读取权限
  • 文件名包含特殊字符(如中文、符号)

安全遍历:添加异常处理

import os

def safe_traverse(root_dir):
    try:
        if not os.path.exists(root_dir):
            print("❌ 路径不存在!")
            return

        if not os.access(root_dir, os.r_ok):
            print("❌ 没有读取权限!")
            return

        print(f"✅ 开始安全遍历: {root_dir}")
        
        for dirpath, dirnames, filenames in os.walk(root_dir):
            print(f"📂 目录: {dirpath}")
            
            for filename in filenames:
                file_path = os.path.join(dirpath, filename)
                try:
                    # 尝试获取文件大小(测试是否可读)
                    size = os.path.getsize(file_path)
                    print(f"📄 {filename} (大小: {size} bytes)")
                except oserror as e:
                    print(f"⚠️ 无法读取文件: {file_path} | 错误: {e}")

    except exception as e:
        print(f"💥 发生未知错误: {e}")

# 调用
safe_traverse("/users/yourname/documents")

关键点

  • 使用 os.path.exists() 判断路径是否存在。
  • 使用 os.access(path, os.r_ok) 检查读权限。
  • os.walk() 内部对每个文件加 try-except,避免因单个文件失败导致整个遍历中断。

高级技巧:按条件筛选文件

很多时候我们不需要遍历所有文件,而是只关心特定类型的文件,比如 .py.log.jpg 等。

示例:只列出.txt和.md文件

import os

def filter_files_by_extension(root_dir, extensions):
    matched_files = []
    
    for dirpath, _, filenames in os.walk(root_dir):
        for filename in filenames:
            if any(filename.lower().endswith(ext.lower()) for ext in extensions):
                full_path = os.path.join(dirpath, filename)
                matched_files.append(full_path)
                print(f"✅ 匹配: {full_path}")
    
    print(f"\n📊 共找到 {len(matched_files)} 个匹配文件。")
    return matched_files

# 使用
txt_md_files = filter_files_by_extension(
    root_dir="/users/yourname/documents",
    extensions=['.txt', '.md']
)

排除特定目录或文件

有时我们需要跳过某些目录,比如 .git__pycache__node_modules 等。

示例:排除隐藏目录和缓存目录

import os

def traverse_with_exclusions(root_dir, exclude_dirs=none):
    if exclude_dirs is none:
        exclude_dirs = {'.git', '__pycache__', 'node_modules', '.venv'}

    print(f"🚀 开始遍历,排除: {exclude_dirs}")

    for dirpath, dirnames, filenames in os.walk(root_dir):
        # 动态过滤掉不想遍历的目录
        dirnames[:] = [d for d in dirnames if d not in exclude_dirs]

        print(f"📂 当前目录: {dirpath}")
        
        for filename in filenames:
            print(f"📄 {filename}")

# 调用
traverse_with_exclusions("/users/yourname/project")

dirnames[:] = [...] 是关键技巧——它修改了 os.walk() 的内部目录列表,实现“跳过”某些子目录。

获取文件详细信息:mtime、ctime、size

除了文件名,我们还常需要知道文件的创建时间、修改时间、大小等元数据。

示例:获取文件详细信息

import os
from datetime import datetime

def get_file_info(root_dir):
    print("📊 文件详细信息汇总:")
    print("-" * 60)

    for dirpath, _, filenames in os.walk(root_dir):
        for filename in filenames:
            file_path = os.path.join(dirpath, filename)
            try:
                stat = os.stat(file_path)
                
                # 转换时间戳为可读格式
                mtime = datetime.fromtimestamp(stat.st_mtime).strftime('%y-%m-%d %h:%m:%s')
                ctime = datetime.fromtimestamp(stat.st_ctime).strftime('%y-%m-%d %h:%m:%s')
                size = stat.st_size
                
                print(f"📄 {filename}")
                print(f"   🕒 修改时间: {mtime}")
                print(f"   🕒 创建时间: {ctime}")
                print(f"   📏 大小: {size} bytes")
                print(f"   📍 路径: {file_path}")
                print("-" * 40)
                
            except exception as e:
                print(f"⚠️ 无法获取信息: {file_path} | 错误: {e}")

get_file_info("/users/yourname/documents")

说明

  • os.stat() 返回文件状态对象。
  • st_mtime: 最后修改时间(modification time)
  • st_ctime: 创建时间(creation time,部分系统支持)
  • st_size: 文件大小(字节)

实战项目:批量重命名文件

假设你要将某个目录下所有的 .jpg 文件重命名为 img_001.jpg, img_002.jpg

示例:自动重命名图片文件

import os

def rename_images_in_folder(folder_path, prefix="img"):
    count = 1
    renamed = 0

    for dirpath, _, filenames in os.walk(folder_path):
        for filename in filenames:
            if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')):
                old_path = os.path.join(dirpath, filename)
                new_filename = f"{prefix}_{count:03d}{os.path.splitext(filename)[1]}"
                new_path = os.path.join(dirpath, new_filename)

                try:
                    os.rename(old_path, new_path)
                    print(f"✅ 重命名: {filename} → {new_filename}")
                    renamed += 1
                    count += 1
                except oserror as e:
                    print(f"❌ 重命名失败: {old_path} → {new_path} | 错误: {e}")

    print(f"🎉 完成!共重命名 {renamed} 个文件。")

# 调用
rename_images_in_folder("/users/yourname/pictures")

 这个脚本可以用于整理照片、清理命名混乱的文件夹。

使用 pathlib 替代 os?—— 一个现代建议

虽然 os 模块功能强大,但 python 3.4+ 推荐使用 pathlib 模块,它更面向对象,语法更清晰。

对比:os vs pathlib

1. 传统 os 写法:

import os

for dirpath, _, filenames in os.walk("/home/user/docs"):
    for f in filenames:
        path = os.path.join(dirpath, f)
        if f.endswith(".log"):
            print(path)

2. 现代 pathlib 写法:

from pathlib import path

root = path("/home/user/docs")
for file_path in root.rglob("*.log"):
    print(file_path)

rglob()glob() 的递归版本,相当于 os.walk() + glob 组合。

单元测试:确保你的遍历逻辑正确

为了保证代码健壮,我们可以写一个简单的测试用例。

import unittest
import os
import tempfile

class testdirectorytraversal(unittest.testcase):

    def setup(self):
        # 创建临时目录结构
        self.temp_dir = tempfile.mkdtemp()
        sub_dir = os.path.join(self.temp_dir, "subfolder")
        os.makedirs(sub_dir)
        
        with open(os.path.join(self.temp_dir, "test1.txt"), "w") as f:
            f.write("hello")
        with open(os.path.join(sub_dir, "test2.py"), "w") as f:
            f.write("print('hi')")

    def teardown(self):
        # 清理临时目录
        os.removedirs(self.temp_dir)

    def test_traverse_with_filter(self):
        from pathlib import path
        matches = list(path(self.temp_dir).rglob("*.txt"))
        self.assertequal(len(matches), 1)
        self.assertin("test1.txt", str(matches[0]))

if __name__ == "__main__":
    unittest.main()

 性能对比:os.walk() vs pathlib.rglob()

方法优点缺点
os.walk()传统、兼容性好、灵活代码略长,需手动拼接路径
pathlib.rglob()语法简洁,可读性强需要 python 3.4+

推荐:新项目优先使用 pathlib,旧项目可保留 os.walk()

实用技巧总结

技巧说明
os.path.join()安全拼接路径,自动适配 os 分隔符
os.path.exists()检查路径是否存在
os.access()检查读写权限
os.stat()获取文件元数据
dirnames[:] = [...]动态跳过子目录
try-except 包裹文件操作防止程序崩溃
pathlib.path().rglob()简洁的递归查找

结语:掌握 os.walk(),就是掌握自动化核心

遍历目录是几乎所有文件处理任务的基础。通过熟练运用 os 模块,尤其是 os.walk(),你可以构建出强大的自动化脚本,用于:

  • 批量处理文件
  • 日志分析
  • 数据备份与迁移
  • 安全扫描
  • 自动化部署

记住:代码不是写出来的,是改出来的。多尝试不同的组合,多加异常处理,你的脚本才会真正“生产可用”。

今天的你,已经掌握了 python 中最实用的文件遍历技能!

现在就动手,打开你的终端,试试这段代码:

import os

for dirpath, dirnames, filenames in os.walk("/your/directory/path"):
    for f in filenames:
        print(f"📄 {os.path.join(dirpath, f)}")

以上就是python如何使用os模块遍历目录下的所有文件的详细内容,更多关于python os模块遍历文件的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com