使用Pathlib实现递归/非递归文件扫描时无输出的问题求助
问题描述
需要实现功能:给定目标目录,当recursive参数为True时递归扫描所有文件,否则仅返回当前目录下的文件。编写的scan_files函数未生成任何文件输出。
代码实现
import re import uuid from pathlib import Path from typing import Generator, Tuple, Union, Optional import time def scan_files(dir_path: Union[str, Path], filter_regex: Optional[str] = None, recursive: bool = True) -> Generator[Tuple[str, Path], None, None]: """ Get list of files in the specified directory. """ path = Path(dir_path) for item in path.iterdir(): if not item.is_symlink(): if recursive and item.is_dir(): yield from scan_files(item, filter_regex=filter_regex) elif filter_regex is None or re.match(filter_regex, item.name, re.IGNORECASE): yield str(uuid.uuid5(uuid.NAMESPACE_URL, str(item))), item while True: print("=" * 100) for x, y in scan_files(dir_path="/tmp/in/106/", recursive=True): print(x, y) print("=" * 100) time.sleep(4)
实际问题
scan_files函数未生成任何文件输出。
测试环境
创建目录/tmp/in/106/nested,添加文件:
/tmp/in/106/1.mov/tmp/in/106/2.mov/tmp/in/106/nested/1.mov/tmp/in/106/nested/2.mov
预期输出
recursive=True时返回所有4个文件的完整路径recursive=False时返回/tmp/in/106/1.mov和/tmp/in/106/2.mov
问题分析
代码存在两个关键问题:
- 未判断条目是否为文件:当前逻辑会把非目录、非符号链接的所有条目都返回,可能包含管道、设备文件等非普通文件;当
recursive=False时,还会误返回目录条目。 - 递归调用未传递
recursive参数:虽然默认值是True,但如果上层调用传入recursive=False,递归调用会错误地使用默认的True,导致不符合预期的递归;同时当前逻辑遗漏了明确的文件判断,可能在某些环境下导致文件未被正确识别。
修复后的代码
import re import uuid from pathlib import Path from typing import Generator, Tuple, Union, Optional import time def scan_files(dir_path: Union[str, Path], filter_regex: Optional[str] = None, recursive: bool = True) -> Generator[Tuple[str, Path], None, None]: """ Get list of files in the specified directory. """ path = Path(dir_path) # 先判断目录是否存在,避免抛出异常 if not path.is_dir(): return for item in path.iterdir(): if not item.is_symlink(): if recursive and item.is_dir(): # 递归调用时传递recursive参数,保持一致的递归行为 yield from scan_files(item, filter_regex=filter_regex, recursive=recursive) elif item.is_file(): # 仅处理文件,避免误返回目录或其他特殊文件 if filter_regex is None or re.match(filter_regex, item.name, re.IGNORECASE): yield str(uuid.uuid5(uuid.NAMESPACE_URL, str(item))), item while True: print("=" * 100) for x, y in scan_files(dir_path="/tmp/in/106/", recursive=True): print(x, y) print("=" * 100) time.sleep(4)
修复说明
- 添加目录存在性检查:避免传入无效路径时抛出异常,直接返回空生成器。
- 仅处理文件条目:通过
item.is_file()确保只返回文件,排除目录和其他特殊文件。 - 递归调用传递
recursive参数:确保递归行为与上层调用的recursive参数一致,避免逻辑矛盾。 - 调整条件判断顺序:先判断是否为文件,再进行正则匹配,逻辑更清晰。
内容的提问来源于stack exchange,提问作者GoneCase123
相关产品推荐
相关产品推荐

