Python递归遍历目录下所有文件查找指定文件

之前看到网上有人说『os.path.isdir()判断必须写绝对路径』,当时心想Python不是有迭代上下文吗,为什么不行?遂作本文验证之


代码部分

考虑用一个path变量指代当前遍历元素的绝对路径(正确做法)

def search(root, target):
    items = os.listdir(root)
    for item in items:
        path = os.path.join(root, item)
        if os.path.isdir(path):
            print('[-]', path)
            search(path, target)
        elif path.split('/')[-1] == target:
            print('[+]', path)
        else:
            print('[!]', path)

正常遍历的结果

这里写图片描述

如果这样写,把路径全部换成item(迭代元素)

def search(root, target):
    items = os.listdir(root)
    for item in items:
        if os.path.isdir(item):
            print('[-]', item)
            search(os.path.join(root, item), target)
        elif item == target:
            print('[+]', os.path.join(root,item))
        else:
            print('[!]', os.path.join(root, item))

这里写图片描述

可以看出,这是行不通的:如果使用item迭代元素进行指代当前路径,最多只会再往下递归两层(子文件夹、子文件夹的文件),可见所未的上下文管理机制在这里是完全不起作用的

反思和总结

1)如果在正确遍历写法基础上,仅改变每次递归时的传递元素迭代机制会做出怎样的反应?

在上面的例子中,只需要把search(os.path.join(root, item), target)改成search(item, target)即可:

这里写图片描述

这一点很容易看出,因为在首次调用search(..)函数时就是传入了一个绝对路径,如果传入相对路径因为没有上下文环境,是不能正确定位文件位置的

2)os.path.abspath(path)方法可以替代os.path.join(root, current)吗?

实践出真知:

这里写图片描述

(大雾)原来os.path.abspath(..)表示的是:相对当前工作目录的相对路径!(而不是相对系统根目录的相对路径!)

所以,os.path.abspath(..)os.path.join(..)是两个完全不同的东西,是不能替换的

3)Python的文件到底是什么呢?

还是那份正确的代码,将每一条输出改成用type(..)函数包裹的形式

这里写图片描述

在看下面另一个例子

这里写图片描述

本着Python中『一切皆对象』的信念,我们输入的路径(包括它的迭代版本、用来接受它的变量)是一个字符串str对象,而用来描述文件的文件句柄(指针)则是一个_io.TextIOWrapper类型的对象

通常我们在文件夹、文件水平查找、筛选,用的是str类型的路径描述,而要对具体某个文件(不是文件夹)进行读或写的操作,就要用到_io.TextIOWrapper类型的文件句柄,它们分的比较细;不像Java中完全被封装成了一个File(String path)对象,它弱化了文件路径的作为单独个体的作用——但是Python则把路径单独拎出来,我们很多的文件操作(广义上比如查找指定文件,不单指文件IO),都是建立在文件路径的基础上的

4)思考:除了开头给出的方法,有没有别的遍历文件办法?

答案是:有的(yes)

这里写图片描述

os.chdir(path)函数可以改变当前工作目录到指定path

但是我们不推荐使用该方法,因为它修改了全局变量,这一点在函数调用前后使用os.getcwd()函数进行验证

先把工作目录切换到根目录下,接着执行自定义的change()函数

这里写图片描述

如你所见,这时候全局的当前工作目录已经发生了改变

猜你喜欢

转载自blog.csdn.net/abc_12366/article/details/80101233