os.scandir比os.listdir快的根本原因在于它返回direntry对象,缓存文件名、类型及stat信息,避免重复系统调用;而os.listdir仅返回字符串列表,后续判断类型或获取元数据需额外调用os.path.isdir()等,引发大量i/o开销。

os.scandir比os.listdir快在哪?
根本原因在于 os.scandir 返回的是 DirEntry 对象,它把文件名、类型、stat 信息(如是否为目录、大小、修改时间)等元数据“懒加载”缓存在首次访问时,避免了对每个文件重复调用 os.stat 或 os.path.isdir。而 os.listdir 只返回纯字符串列表,后续要判断类型或获取大小,必须额外调用系统函数——这在大量小文件场景下会触发成千上万次系统调用,成为性能瓶颈。
怎么安全地把os.listdir换成os.scandir?
不能直接替换返回值,因为 os.scandir 返回可迭代的 DirEntry 对象,不是字符串列表。常见错误是写成 for entry in os.scandir(path): print(entry) 却忘了用 entry.name 或 entry.path 取路径名。
- 要获取文件名:用
entry.name(相对路径名),不是str(entry) - 要拼完整路径:推荐
os.path.join(path, entry.name),而非entry.path(后者在某些平台可能未填充) - 判断是否为目录:优先用
entry.is_dir(),它比os.path.isdir(os.path.join(...))快且线程安全 - 需要文件大小或修改时间:用
entry.stat().st_size或entry.stat().st_mtime,stat()结果会被缓存,多次调用不重复系统调用
示例:只列出子目录名
with os.scandir(path) as it:
for entry in it:
if entry.is_dir():
print(entry.name)
为什么用了scandir还是没变快?
常见陷阱有三个:
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 没加
with语句:os.scandir返回的对象需及时关闭,否则资源泄漏,尤其在循环中反复调用时;不加with可能导致句柄耗尽或结果不一致 - 误用
entry.path拼接再调os.path.isdir:这绕过了DirEntry的优化,又触发一次系统调用 - 在 Windows 上对符号链接调
is_dir(follow_symlinks=True)(默认行为):若目标不可达,会抛OSError;需显式设follow_symlinks=False并捕获异常
跨平台兼容要注意什么?
os.scandir 自 Python 3.5 起内置,但早期版本(如 3.4)需回退到 os.listdir + 手动 stat。如果必须支持旧版本,可用 try/except ImportError 包裹,或直接依赖 scandir 第三方包(pip install scandir)。
另外,DirEntry 的 is_file()、is_dir() 在不同系统对“不可访问路径”的行为略有差异:Linux 可能静默返回 False,Windows 更倾向抛 PermissionError。实际遍历时建议始终包裹 try/except (OSError, PermissionError)。
真正影响性能的从来不是函数名换没换,而是你有没有让 is_dir() 和 stat() 这两个动作落在同一个 DirEntry 实例上——少一次系统调用,就少一次上下文切换和磁盘寻道。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










