← 返回题目列表

Python 如何遍历目录?os.walk、pathlib、glob 有什么区别?

高频 简单 第 1 / 27 题 更新于 2026/07/31
目录遍历os.walkpathlibglob

简化版

遍历目录常用 os.walk()pathlib.Path.rglob()glob.glob()os.walk() 返回目录、子目录和文件名,适合精细控制;pathlib 面向对象、可读性好;glob 用通配模式匹配路径,适合按模式找文件。

详细版

如果要递归遍历所有文件:

from pathlib import Path

for path in Path("logs").rglob("*.log"):
    print(path)

如果要控制是否进入某些目录:

for root, dirs, files in os.walk("logs"):
    dirs[:] = [d for d in dirs if d != ".git"]

glob 更像按模式搜索,pathlib 更适合现代代码组织,os.walk 在需要原地修改 dirs、处理大量文件、兼容旧代码时仍常用。

完整版教学

一、目录遍历为什么容易踩坑

目录遍历看起来只是列文件,但真实场景会遇到递归、隐藏目录、符号链接、权限错误、路径分隔符、文件数量巨大等问题。写得粗糙会漏文件、重复遍历或性能很差。

project/
  logs/
  .git/
  data/
  link -> ../project

如果跟随符号链接,甚至可能形成循环。面试回答要体现这些边界。

二、os.walk 怎么用

os.walk(top) 每次返回 (root, dirs, files)root 是当前目录,dirs 是子目录名列表,files 是文件名列表。

import os

for root, dirs, files in os.walk("src"):
    for name in files:
        print(os.path.join(root, name))

默认自顶向下遍历。自顶向下时,可以原地修改 dirs[:] 来跳过某些目录。

dirs[:] = [d for d in dirs if d not in {".git", "__pycache__"}]

三、pathlib 为什么更推荐

pathlib.Path 把路径当对象,拼接、判断、读取都更直观,跨平台分隔符也更舒服。现代 Python 项目通常更推荐 pathlib。

from pathlib import Path

root = Path("src")
for file in root.rglob("*.py"):
    print(file.name, file.parent)
操作os.pathpathlib
拼路径os.path.join(a,b)Path(a) / b
判断文件os.path.isfile(p)p.is_file()
递归匹配os.walk + 判断Path.rglob()

新代码优先考虑 pathlib,读老代码要熟悉 os.walk。

四、glob 适合什么

glob 用 shell 风格通配符匹配路径。比如 *.py 匹配当前目录 Python 文件,**/*.py 配合 recursive 匹配递归文件。

import glob

glob.glob("src/**/*.py", recursive=True)

pathlib 也有 globrglob,多数新代码可以直接用 Path.rglob("*.py")

五、性能和内存要注意什么

glob.glob() 返回列表,匹配结果很多时会一次性占内存。glob.iglob() 返回迭代器,更适合大目录。Path.rglob() 也是迭代式产生路径。

for path in glob.iglob("logs/**/*.log", recursive=True):
    handle(path)

如果目录里有 100 万文件,一次性列表会占不少内存;迭代处理更稳。

六、权限和符号链接如何处理

遍历系统目录时可能遇到权限错误。os.walkonerror 参数;pathlib 遍历时需要捕获 OSError。符号链接是否跟随也要明确。

def onerror(err):
    print("skip", err.filename)

for root, dirs, files in os.walk("/", onerror=onerror):
    ...

跟随符号链接可能导致循环或重复扫描。备份、清理工具尤其要谨慎。

七、常见误区与追问

  • 误区:glob 默认递归。 ** 需要配合 recursive 或 pathlib 的 rglob。
  • 误区:遍历目录不会出错。 权限、删除中的文件、符号链接都会导致异常。
  • 误区:一次性拿列表总没问题。 大目录会消耗大量内存,优先迭代处理。
  • 追问:如何跳过 .git? os.walk 自顶向下时修改 dirs[:]
  • 追问:pathlib 和 os.path 怎么选? 新代码 pathlib 可读性好,老代码 os.path 常见。
  • 追问:如何只找某类文件? glob/rglob 模式,或遍历后判断 suffix。
  • 追问:符号链接要不要跟随? 看业务,默认谨慎,避免循环。

八、加强记忆

目录遍历记成“三件工具”:os.walk 精细控制,pathlib.rglob 现代好读,glob 模式匹配。大目录用迭代,跳目录改 dirs[:],权限和符号链接要防。会这些,比只写一个递归函数稳得多。