解锁Python文件遍历新姿势glob模块的5个高阶技巧在Python开发者的日常工作中文件遍历几乎是无法绕开的任务。无论是日志分析、数据集整理还是自动化测试我们都需要频繁地与文件系统打交道。很多开发者习惯性地使用os.listdir()或手动递归来处理这些需求却不知道Python标准库中隐藏着一个更强大的工具——glob模块。1. 为什么glob比传统方法更值得选择1.1 os.listdir的局限性os.listdir()是大多数Python开发者接触的第一个文件遍历方法。它简单直接返回指定路径下的所有文件和子目录列表。但在实际项目中我们很快就会发现它的不足import os # 基本用法 files os.listdir(data/) print(files) # 输出所有文件和目录需要额外处理才能区分主要问题包括无法直接过滤文件类型需要手动处理路径拼接不支持递归遍历子目录缺乏模式匹配能力1.2 os.walk的复杂性当需要递归遍历目录时很多开发者会转向os.walk()for root, dirs, files in os.walk(data/): for file in files: if file.endswith(.csv): print(os.path.join(root, file))虽然功能强大但存在以下痛点代码冗长需要多层循环过滤逻辑需要手动实现返回结构复杂三个列表模式匹配能力有限1.3 glob的优雅解决方案相比之下glob模块提供了更简洁的APIimport glob # 简单匹配 csv_files glob.glob(data/*.csv) print(csv_files) # 直接得到匹配的完整路径列表 # 递归匹配 all_csv glob.glob(data/**/*.csv, recursiveTrue)优势对比表特性os.listdiros.walkglob单层遍历✓✓✓递归遍历✗✓✓内置模式匹配✗✗✓路径自动拼接✗✓✓代码简洁度中等复杂简单返回结果直接可用度低中高2. glob的5个高阶技巧2.1 递归通配符一键遍历所有子目录**是glob中最强大的通配符之一配合recursiveTrue参数可以实现全目录递归搜索# 查找项目中的所有Python文件 py_files glob.glob(**/*.py, recursiveTrue) # 查找特定子目录下的图片 images glob.glob(static/**/*.jpg, recursiveTrue)注意在Windows系统中路径分隔符会自动转换为反斜杠但模式匹配中应始终使用正斜杠(/)2.2 字符集匹配精准定位特定文件glob支持类似正则表达式的字符集匹配但语法更简单# 匹配log2021.log到log2029.log decade_logs glob.glob(logs/log202[1-9].log) # 匹配test1.py到test9.py single_digit_tests glob.glob(tests/test[1-9].py) # 匹配a.txt或b.txt但不包括c.txt select_files glob.glob(data/[ab].txt)字符集规则[abc]匹配a、b或c[a-z]匹配任何小写字母[0-9]匹配任何数字[!a]匹配非a的字符2.3 问号通配符固定长度模糊匹配当你知道文件名长度但不确定具体字符时?通配符非常有用# 匹配所有3字符名称的CSV文件 three_char_csv glob.glob(data/???.csv) # 匹配img_后面跟2个字符的PNG图片 specific_images glob.glob(images/img_??.png)2.4 组合模式构建复杂匹配逻辑通过组合不同的通配符可以创建复杂的匹配模式# 匹配2020-2029年每月的数据文件 yearly_data glob.glob(data/202[0-9]-[01][0-9].csv) # 匹配以test开头接着是1-5的数字最后是_a或_b的.py文件 complex_test glob.glob(tests/test[1-5]_[ab].py)2.5 与pathlib结合面向对象的优雅操作Python 3.4引入了pathlib模块它与glob完美配合from pathlib import Path # 使用Path对象的glob方法 py_files list(Path(.).glob(**/*.py)) # 更复杂的匹配 images list(Path(static).glob(*.[pj][np]g)) # 匹配.png和.jpgpathlibglob的优势链式调用更流畅路径操作更安全返回的是Path对象而非字符串跨平台兼容性更好3. 性能优化与实战技巧3.1 缓存机制提升重复查询速度对于需要多次执行相同glob模式的情况可以预先编译模式import glob import fnmatch pattern data/*.csv matcher fnmatch.translate(pattern) # 转换为正则表达式 compiled re.compile(matcher) # 后续使用编译后的模式进行匹配 [csv for csv in os.listdir(data) if compiled.match(csv)]3.2 处理大型目录结构的策略当处理包含数万文件的目录时可以考虑使用iglob替代glob获取生成器而非列表large_files glob.iglob(big_data/**/*.log, recursiveTrue) for file in large_files: process(file)分批次处理batch_size 1000 files list(glob.iglob(huge_dir/**/*.json, recursiveTrue)) for i in range(0, len(files), batch_size): batch files[i:ibatch_size] process_batch(batch)3.3 常见陷阱与解决方案问题1隐藏文件被忽略glob默认不匹配以点开头的文件Unix隐藏文件解决方法# 匹配包括隐藏文件在内的所有文件 all_files glob.glob(.*) glob.glob(*)问题2跨平台路径分隔符Windows使用反斜杠而Unix使用正斜杠最佳实践# 总是使用正斜杠编写模式 files glob.glob(data/**/*.csv, recursiveTrue) # 需要处理路径时使用os.path或pathlib import os.path full_path os.path.join(data, subdir, file.csv)问题3符号链接循环递归遍历时可能遇到符号链接导致的无限循环防护措施def safe_glob(pattern): seen set() for file in glob.iglob(pattern, recursiveTrue): real_path os.path.realpath(file) if real_path not in seen: seen.add(real_path) yield file4. 真实项目应用案例4.1 日志分析系统假设我们需要分析分布在多个目录中的服务器日志def analyze_logs(): log_patterns [ /var/log/app/*.log, /var/log/app/archive/**/*.log, /var/log/app/*/error_*.log ] for pattern in log_patterns: for log_file in glob.iglob(pattern, recursiveTrue): with open(log_file) as f: process_log(f.read())4.2 图片资源整理整理散落在不同目录的图片资源def organize_images(target_dirorganized_images): image_exts [*.jpg, *.png, *.gif] os.makedirs(target_dir, exist_okTrue) for ext in image_exts: for img_path in glob.iglob(f**/{ext}, recursiveTrue): date get_image_date(img_path) # 假设的函数 dest_dir os.path.join(target_dir, date) os.makedirs(dest_dir, exist_okTrue) shutil.copy2(img_path, dest_dir)4.3 自动化测试发现动态发现并运行测试用例def discover_tests(): test_files glob.glob(tests/**/test_*.py, recursiveTrue) for file in test_files: module_name file.replace(/, .).replace(\\, .)[:-3] __import__(module_name) # 动态导入测试模块4.4 数据管道构建构建数据处理管道时收集输入文件class DataPipeline: def __init__(self, input_patterns): self.input_files [] for pattern in input_patterns: self.input_files.extend(glob.glob(pattern, recursiveTrue)) def process(self): for file in self.input_files: data load_data(file) # 假设的数据加载函数 transformed transform(data) save_results(transformed)5. 进阶模式与替代方案5.1 自定义匹配函数当内置模式不能满足需求时可以结合过滤函数def find_recent_files(pattern, days7): now time.time() cutoff now - days * 86400 for file in glob.iglob(pattern, recursiveTrue): if os.path.getmtime(file) cutoff: yield file5.2 与正则表达式结合对于更复杂的匹配需求可以将glob与re模块结合import re def glob_re(pattern, string): # 将glob模式转换为正则表达式 regex fnmatch.translate(pattern) return re.fullmatch(regex, string) is not None # 使用示例 files [f for f in os.listdir() if glob_re(data_[0-9][0-9].csv, f)]5.3 替代方案对比虽然glob很强大但某些场景下其他工具可能更合适场景推荐工具理由极大量文件(百万)os.scandir内存效率更高需要文件元信息pathlib直接获取stat信息复杂条件过滤os.listdirfilter更灵活的编程控制实时监控文件系统变化watchdog专门的文件系统事件监控库跨平台特殊字符处理pathlib自动处理平台差异
别再只用os.listdir了!Python文件遍历,用glob模块这5个技巧更高效
发布时间:2026/6/10 12:06:05
解锁Python文件遍历新姿势glob模块的5个高阶技巧在Python开发者的日常工作中文件遍历几乎是无法绕开的任务。无论是日志分析、数据集整理还是自动化测试我们都需要频繁地与文件系统打交道。很多开发者习惯性地使用os.listdir()或手动递归来处理这些需求却不知道Python标准库中隐藏着一个更强大的工具——glob模块。1. 为什么glob比传统方法更值得选择1.1 os.listdir的局限性os.listdir()是大多数Python开发者接触的第一个文件遍历方法。它简单直接返回指定路径下的所有文件和子目录列表。但在实际项目中我们很快就会发现它的不足import os # 基本用法 files os.listdir(data/) print(files) # 输出所有文件和目录需要额外处理才能区分主要问题包括无法直接过滤文件类型需要手动处理路径拼接不支持递归遍历子目录缺乏模式匹配能力1.2 os.walk的复杂性当需要递归遍历目录时很多开发者会转向os.walk()for root, dirs, files in os.walk(data/): for file in files: if file.endswith(.csv): print(os.path.join(root, file))虽然功能强大但存在以下痛点代码冗长需要多层循环过滤逻辑需要手动实现返回结构复杂三个列表模式匹配能力有限1.3 glob的优雅解决方案相比之下glob模块提供了更简洁的APIimport glob # 简单匹配 csv_files glob.glob(data/*.csv) print(csv_files) # 直接得到匹配的完整路径列表 # 递归匹配 all_csv glob.glob(data/**/*.csv, recursiveTrue)优势对比表特性os.listdiros.walkglob单层遍历✓✓✓递归遍历✗✓✓内置模式匹配✗✗✓路径自动拼接✗✓✓代码简洁度中等复杂简单返回结果直接可用度低中高2. glob的5个高阶技巧2.1 递归通配符一键遍历所有子目录**是glob中最强大的通配符之一配合recursiveTrue参数可以实现全目录递归搜索# 查找项目中的所有Python文件 py_files glob.glob(**/*.py, recursiveTrue) # 查找特定子目录下的图片 images glob.glob(static/**/*.jpg, recursiveTrue)注意在Windows系统中路径分隔符会自动转换为反斜杠但模式匹配中应始终使用正斜杠(/)2.2 字符集匹配精准定位特定文件glob支持类似正则表达式的字符集匹配但语法更简单# 匹配log2021.log到log2029.log decade_logs glob.glob(logs/log202[1-9].log) # 匹配test1.py到test9.py single_digit_tests glob.glob(tests/test[1-9].py) # 匹配a.txt或b.txt但不包括c.txt select_files glob.glob(data/[ab].txt)字符集规则[abc]匹配a、b或c[a-z]匹配任何小写字母[0-9]匹配任何数字[!a]匹配非a的字符2.3 问号通配符固定长度模糊匹配当你知道文件名长度但不确定具体字符时?通配符非常有用# 匹配所有3字符名称的CSV文件 three_char_csv glob.glob(data/???.csv) # 匹配img_后面跟2个字符的PNG图片 specific_images glob.glob(images/img_??.png)2.4 组合模式构建复杂匹配逻辑通过组合不同的通配符可以创建复杂的匹配模式# 匹配2020-2029年每月的数据文件 yearly_data glob.glob(data/202[0-9]-[01][0-9].csv) # 匹配以test开头接着是1-5的数字最后是_a或_b的.py文件 complex_test glob.glob(tests/test[1-5]_[ab].py)2.5 与pathlib结合面向对象的优雅操作Python 3.4引入了pathlib模块它与glob完美配合from pathlib import Path # 使用Path对象的glob方法 py_files list(Path(.).glob(**/*.py)) # 更复杂的匹配 images list(Path(static).glob(*.[pj][np]g)) # 匹配.png和.jpgpathlibglob的优势链式调用更流畅路径操作更安全返回的是Path对象而非字符串跨平台兼容性更好3. 性能优化与实战技巧3.1 缓存机制提升重复查询速度对于需要多次执行相同glob模式的情况可以预先编译模式import glob import fnmatch pattern data/*.csv matcher fnmatch.translate(pattern) # 转换为正则表达式 compiled re.compile(matcher) # 后续使用编译后的模式进行匹配 [csv for csv in os.listdir(data) if compiled.match(csv)]3.2 处理大型目录结构的策略当处理包含数万文件的目录时可以考虑使用iglob替代glob获取生成器而非列表large_files glob.iglob(big_data/**/*.log, recursiveTrue) for file in large_files: process(file)分批次处理batch_size 1000 files list(glob.iglob(huge_dir/**/*.json, recursiveTrue)) for i in range(0, len(files), batch_size): batch files[i:ibatch_size] process_batch(batch)3.3 常见陷阱与解决方案问题1隐藏文件被忽略glob默认不匹配以点开头的文件Unix隐藏文件解决方法# 匹配包括隐藏文件在内的所有文件 all_files glob.glob(.*) glob.glob(*)问题2跨平台路径分隔符Windows使用反斜杠而Unix使用正斜杠最佳实践# 总是使用正斜杠编写模式 files glob.glob(data/**/*.csv, recursiveTrue) # 需要处理路径时使用os.path或pathlib import os.path full_path os.path.join(data, subdir, file.csv)问题3符号链接循环递归遍历时可能遇到符号链接导致的无限循环防护措施def safe_glob(pattern): seen set() for file in glob.iglob(pattern, recursiveTrue): real_path os.path.realpath(file) if real_path not in seen: seen.add(real_path) yield file4. 真实项目应用案例4.1 日志分析系统假设我们需要分析分布在多个目录中的服务器日志def analyze_logs(): log_patterns [ /var/log/app/*.log, /var/log/app/archive/**/*.log, /var/log/app/*/error_*.log ] for pattern in log_patterns: for log_file in glob.iglob(pattern, recursiveTrue): with open(log_file) as f: process_log(f.read())4.2 图片资源整理整理散落在不同目录的图片资源def organize_images(target_dirorganized_images): image_exts [*.jpg, *.png, *.gif] os.makedirs(target_dir, exist_okTrue) for ext in image_exts: for img_path in glob.iglob(f**/{ext}, recursiveTrue): date get_image_date(img_path) # 假设的函数 dest_dir os.path.join(target_dir, date) os.makedirs(dest_dir, exist_okTrue) shutil.copy2(img_path, dest_dir)4.3 自动化测试发现动态发现并运行测试用例def discover_tests(): test_files glob.glob(tests/**/test_*.py, recursiveTrue) for file in test_files: module_name file.replace(/, .).replace(\\, .)[:-3] __import__(module_name) # 动态导入测试模块4.4 数据管道构建构建数据处理管道时收集输入文件class DataPipeline: def __init__(self, input_patterns): self.input_files [] for pattern in input_patterns: self.input_files.extend(glob.glob(pattern, recursiveTrue)) def process(self): for file in self.input_files: data load_data(file) # 假设的数据加载函数 transformed transform(data) save_results(transformed)5. 进阶模式与替代方案5.1 自定义匹配函数当内置模式不能满足需求时可以结合过滤函数def find_recent_files(pattern, days7): now time.time() cutoff now - days * 86400 for file in glob.iglob(pattern, recursiveTrue): if os.path.getmtime(file) cutoff: yield file5.2 与正则表达式结合对于更复杂的匹配需求可以将glob与re模块结合import re def glob_re(pattern, string): # 将glob模式转换为正则表达式 regex fnmatch.translate(pattern) return re.fullmatch(regex, string) is not None # 使用示例 files [f for f in os.listdir() if glob_re(data_[0-9][0-9].csv, f)]5.3 替代方案对比虽然glob很强大但某些场景下其他工具可能更合适场景推荐工具理由极大量文件(百万)os.scandir内存效率更高需要文件元信息pathlib直接获取stat信息复杂条件过滤os.listdirfilter更灵活的编程控制实时监控文件系统变化watchdog专门的文件系统事件监控库跨平台特殊字符处理pathlib自动处理平台差异