【笔记】Python 实现目录及子目录文件的查找

时间:2022-05-04 12:09:31

今天绕这个东西弄了一天,虽然很简单,但还是总结下吧

1. 问题描述

来自廖雪峰网站,操作文件和目录一节的习题

编写一个程序,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径。

2. 问题分析

2.1 知识点

这节主要讲了通过import os模块中提供的功能,实现python对操作系统中文件和目录的操作。习题相关的主要函数有:

  • os.path.abspath(path),显示path在操作系统中的绝对路径
  • os.path.join(path, x),将pathx拼接成当前操作系统兼容的路径形式
  • os.listdir(path),输出当前目录下的文件及子目录为list类型
  • os.path.isdir(path) and os.path.isfile(path)判断路径为目录还是文件,注意参数为path,之前在这里出现了很多错误,直接输文件名的话,没有该文件就直接显示False

2.2 分析

主要思路是,根据输入的路径及搜索字符串,先搜索当前目录下文件。

接下来,进入子目录,执行搜索操作,考虑到嵌套目录,所以程序应当是递归操作比较简单。

很久没有编程动脑子,递归这些东西绕的有点晕,浪费了很多时间。

3. 代码实现

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os


# find_cur(string, path)实现对path目录下文件的查找,列出文件命中含string的文件
def find_cur(string, path):
# print('cur_dir is %s' % os.path.abspath(path))
l = []

# 遍历当前文件,找出符合要求的文件,将路径添加到l中
for x in os.listdir(path):
if os.path.isfile(path+'/'+x):
if string in x:
l.append(os.path.abspath(x))
if not l:
print('no %s in %s' % (string, os.path.abspath(path1)))
else:
print(l)


# deeper_dir(string, p)主要通过递归,在每个子目录中调用find_cur()
def deeper_dir(string='', p='..'): # '.'表示当前路径,'..'表示当前路径的父目录
find_cur(string, p)
for x in os.listdir(p):
# 关键,将父目录的路径保留下来,保证在完成子目录的查找之后能够返回继续遍历。
pp = p
if os.path.isdir(pp):
pp = os.path.join(pp, x)
if os.path.isdir(pp):
deeper_dir(string, pp)

if __name__=='__main__':
deeper_dir()

感觉find_curdeeper_dir中的循环有重合的部分,应该还有优化的空间,这个等什么时候脑子清醒点再弄吧。。。

4. 优化

偶然在这里看到了比较简洁的遍历方法,初学python的人写的。。。唉,差距啊

Python遍历路径下文件,分别是不使用walk和使用walk的。

代码是我优化过的版本:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os


def find_dir(string, path='..'):
print('cur dir:%s' % os.path.abspath(path))
for filename in os.listdir(path):
deeper_dir = os.path.join(path, filename)
if os.path.isfile(deeper_dir) and string in filename:
print('%s with \'t\' in its name' % filename)
if os.path.isdir(deeper_dir):
find_dir(string, deeper_dir)

if __name__ == '__main__':
find_dir('t')

从上面的代码可以看出,如果把刚开始的代码精简一下,理顺了基本就是这样的结果,可惜经验太少,把自己绕糊涂了,不过刚开始,继续加油吧。

import os

def detect_walk(dir_path):
for root, dirs, files in os.walk(dir_path):
for filename in files:
print "file:%s\n" % filename
for dirname in dirs:
print "dir:%s\n" % dirname

if __name__ == "__main__":
detect_walk(".")

os.walk()可以不用考虑通过递归遍历目录及其子目录的问题,直接调用操作就好了,十分简单清楚,只是之前没有好好理解os.walk()的用法。所以这方面能力也是很重要的,别人造好的*也要知道怎么用才好。