代碼如下
import os def find_file(search_path, file_type="file", filename=None, file_startswith=None, file_endswith=None, abspath=False) -> dict: """ 查找指定目錄下所有的文件(不包含以__開頭和結尾的文件)或指定格式的文件,若不同目錄存在相同文件名,只返回第1個文件的路徑 :param search_path: 查找的目錄路徑 :param file_type: 查找的類型,可缺省,缺省則默認查找文件類型,可輸入值:file和dir,file表示文件,dir表示目錄 :param filename: 查找名稱,精確匹配,可缺省,缺省則返回所有文件或目錄,不可與file_startswith或file_endswith組合使用 :param file_startswith: 模糊匹配開頭,可缺省,缺省則不匹配,可與file_endswith組合使用 :param file_endswith: 模糊匹配結尾,可缺省,缺省則不匹配 :param abspath: 是否返回絕對路徑,默認返回相對路徑 :return: 有結果返回dict類型,key為文件名,value為文件路徑,無結果返None """ filename_path = {} the_filename_path = {} if abspath: search_path = os.path.abspath(search_path) if file_type not in ["file", "dir"]: raise ValueError(f"file_type只能為file或dir,而輸入值為{file_type}") def __find_file(_search_path): # 返回目錄所有名稱 names = os.listdir(_search_path) find_flag = False # 如果查找指定文件,找到就停止查找 if filename is not None and (filename in names): path = os.path.join(_search_path, filename) if file_type == "file" and os.path.isfile(path): the_filename_path.setdefault(filename, path) find_flag = True elif file_type == "dir" and os.path.isdir(path): the_filename_path.setdefault(filename, path) find_flag = True return find_flag # 如果根目錄未找到,在子目錄繼續查找 for name in names: # 過濾以__開頭和__結尾的目錄,以及__init__.py文件 if name.startswith("__") and name.endswith("__") or name == "__init__.py": continue child_path = os.path.join(_search_path, name) # 如果是文件就保存 if file_type == "file" and os.path.isfile(child_path): if file_startswith is None and file_endswith is None: filename_path.setdefault(name, child_path) # 保存指定結尾的文件 elif file_startswith is not None and file_endswith is None and name.startswith(file_startswith): filename_path.setdefault(name, child_path) elif file_startswith is None and file_endswith is not None and name.endswith(file_endswith): filename_path.setdefault(name, child_path) elif file_startswith is not None and file_endswith is not None and name.startswith(file_startswith) and name.endswith(file_endswith): filename_path.setdefault(name, child_path) continue if os.path.isdir(child_path): if file_type == "dir": if file_startswith is None and file_endswith is None: filename_path.setdefault(name, child_path) # 保存指定結尾的文件 elif file_startswith is not None and file_endswith is None and name.startswith(file_startswith): filename_path.setdefault(name, child_path) elif file_startswith is None and file_endswith is not None and name.endswith(file_endswith): filename_path.setdefault(name, child_path) elif file_startswith is not None and file_endswith is not None and name.startswith(file_startswith) and name.endswith(file_endswith): filename_path.setdefault(name, child_path) _result = __find_file(child_path) if _result is True: return _result result = __find_file(search_path) if filename is None: if filename_path: return filename_path if filename is not None: if result is True: return the_filename_path
目錄結構
用法演示
if __name__ == '__main__': # 目錄下不存在文件時 start_path = r".\二級目錄" ret = find_file(start_path) print("目錄下不存在文件時:%s" % ret) assert ret is None print("="*60) start_path = r".\一級目錄" # 查找所有文件或目錄 ret = find_file(start_path, file_type="file") print("查找所有文件:%s" % ret) assert len(ret) == 4 ret = find_file(start_path, file_type="dir") print("查找所有目錄:%s" % ret) assert len(ret) == 4 print("="*60) # 查找指定開始的所有文件 ret = find_file(start_path, file_startswith="次級") print("查找指定開始的文件:%s" % ret) assert "次級目錄1中的文件.py" in ret ret = find_file(start_path, file_type="file", file_startswith="哈哈") print("查找指定開始的文件不存在時:%s" % ret) assert ret is None print("="*60) # 查找指定結尾的所有文件 ret = find_file(start_path, file_endswith="txt") print("查找指定結尾的文件:%s" % ret) assert "一級目錄的文件.txt" in ret ret = find_file(start_path, file_type="file", file_endswith="哈哈") print("查找指定結尾的文件不存在時:%s" % ret) assert ret is None print("="*60) # 查找指定開頭和指定結尾的所有文件 ret = find_file(start_path, file_startswith="次級", file_endswith="txt") print("查找指定開頭和指定結尾的所有文件:%s" % ret) assert "次級目錄2中的文件.txt" == list(ret.keys())[0] ret = find_file(start_path, file_startswith="呵呵", file_endswith="txt") print("查找指定開始不存在,指定結尾存在時:%s" % ret) assert ret is None ret = find_file(start_path, file_startswith="次級", file_endswith="哈哈") print("查找指定開始存在,指定結尾不存在時:%s" % ret) assert ret is None ret = find_file(start_path, file_startswith="呵呵", file_endswith="哈哈") print("查找指定開始和指定結尾都不存在時:%s" % ret) assert ret is None print("="*60) # 查找指定開始的所有文件 ret = find_file(start_path, file_type="dir", file_startswith="次級") print("查找指定開始的文件:%s" % ret) assert "次級目錄1中的三級目錄" in ret ret = find_file(start_path, file_type="dir", file_startswith="哈哈") print("查找指定開始的文件不存在時:%s" % ret) assert ret is None print("="*60) # 查找指定結尾的所有目錄 ret = find_file(start_path, file_type="dir", file_endswith="目錄") print("查找指定結尾的目錄:%s" % ret) assert len(ret) == 2 ret = find_file(start_path, file_type="dir", file_endswith="哈哈") print("查找指定結尾的目錄不存在時:%s" % ret) assert ret is None print("="*60) # 查找指定開頭和指定結尾的所有目錄 ret = find_file(start_path, file_type="dir", file_startswith="次級", file_endswith="目錄") print("查找指定開頭和指定結尾的所有文件:%s" % ret) assert "次級目錄2中的目錄" in ret ret = find_file(start_path, file_type="dir", file_startswith="呵呵", file_endswith="目錄") print("查找指定開始不存在,指定結尾存在時:%s" % ret) assert ret is None ret = find_file(start_path, file_type="dir", file_startswith="次級", file_endswith="哈哈") print("查找指定開始存在,指定結尾不存在時:%s" % ret) assert ret is None ret = find_file(start_path, file_type="dir", file_startswith="呵呵", file_endswith="哈哈") print("查找指定開始和指定結尾都不存在時:%s" % ret) assert ret is None print("="*60) # 查找指定文件 ret = find_file(start_path, file_type="file", filename="三級目錄中的文件.yaml") print("查找指定文件:%s" % ret) assert len(ret) == 1 ret = find_file(start_path, file_type="file", filename="asd") print("查找不存在的文件:%s" % ret) assert ret is None ret = find_file(start_path, file_type="file", filename="次級目錄1中的三級目錄") print("以文件類型去查找已存在文件:%s" % ret) assert ret is None print("=" * 60) # 查找指定目錄 ret = find_file(start_path, file_type="dir", filename="次級目錄1中的三級目錄") print("查找指定目錄:%s" % ret) assert len(ret) == 1 ret = find_file(start_path, file_type="dir", filename="asd") print("查找不存在的目錄:%s" % ret) assert ret is None ret = find_file(start_path, file_type="dir", filename="三級目錄中的文件.yaml") print("以目錄類型去查找已存在文件:%s" % ret) assert ret is None
演示結果