You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

os.walk与glob.glob返回结果不一致的技术咨询

os.walk与glob.glob查找Python文件的差异原因

核心差异:隐藏目录的匹配规则

  1. glob.glob的默认行为
    Python的glob模块默认会忽略以.开头的文件和目录(即系统定义的隐藏文件/目录),除非匹配模式中明确包含.。当使用**/*.py并设置recursive=True时,**不会遍历名称以.开头的子目录(比如.venv),因此这些目录下的.py文件不会被匹配到——这就是你用glob找不到.venv路径下pyparsing.py的原因。

而名称不以.开头的目录(比如venv)不在glob的忽略范围内,**会正常遍历这类目录,所以glob能找到其中的.py文件。

  1. os.walk的遍历逻辑
    os.walk会遍历指定根目录下的所有子目录,不管目录名称是否以.开头,也不会默认忽略任何目录(除非你手动修改dirnames列表排除目录)。因此它能正常找到.venv目录下的.py文件。

为什么os.walk没找到部分venv下的文件?

你提到os.walk未返回部分含/venv/的文件,可能的原因包括:

  • 部分venv目录是符号链接:os.walk默认参数followlinks=False,不会跟随符号链接目录;而glob.glob在recursive=True时会跟随符号链接(取决于系统和Python版本),导致这部分文件只被glob捕获。
  • 代码缩进错误:你提供的os.walk代码中,for循环前有多余缩进,这会引发语法错误。如果实际运行的代码存在类似问题,可能导致部分目录未被遍历。
  • 系统权限限制:部分venv目录下的文件可能存在权限问题,os.walk无法访问,而glob在遍历过程中的权限处理逻辑不同,跳过了这类限制。

统一结果的解决方案

如果想让两种方法返回一致的结果,可以做以下调整:

  • 让glob匹配隐藏目录:Python 3.13+版本新增了include_hidden参数,开启后可匹配隐藏目录:
    repos_path = f"{os.path.dirname(__file__)}/repos"
    pyfiles = glob.glob(f"{repos_path}/**/*.py", recursive=True, include_hidden=True)
    
  • 让os.walk排除指定目录:在遍历过程中手动移除不需要的目录,避免无效遍历:
    abs_paths = []
    repos_path = f"{os.path.dirname(__file__)}/repos"
    for dirpath, dirnames, filenames in os.walk(repos_path):
        # 移除venv和.venv目录,不遍历其下内容
        dirnames[:] = [d for d in dirnames if d not in ('venv', '.venv')]
        for f in filenames:
            abs_path = os.path.join(dirpath, f)
            if abs_path.endswith(".py"):
                abs_paths.append(abs_path)
    

内容的提问来源于stack exchange,提问作者MPP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 13:54:36