Python学习笔记之os.walk()函数

  • Post author:
  • Post category:python



我们使用os,listdir()函数来列出目录下的所有文件和目录放入一个列表进行返回,但是listdir()函数不可对目录的子目录进行扫描。

print(os.listdir('/'))

输出:

['boot', 'dev', 'home', 'proc', 'run', 'sys', 'etc', 'root', 'var', 'tmp', 'usr', 'bin', 'sbin', 'lib', 'lib64', 'media', 'mnt', 'opt', 'srv', 'iso', 'redhat7.4-mount', '.autorelabel', 'directory', 'python']

很多时候我们需要将某个文件夹下的所有文件都要找出来,那么此时我们就需要os.walk()函数。os.walk()方法用于通过在目录了数中向下或向上游走,输出目录的文件名,该方法回访回一个生成器。

os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]])
top 	-- 是你所要遍历的目录的地址.
topdown -- 可选,为 True,则优先遍历top目录,
	   否则优先遍历 top 的子目录(默认为开启)。
onerror -- 可选,需要一个 callable 对象,当 walk 需要异常时,会调用。
followlinks -- 可选,如果为 True,则会遍历目录下的快捷方式,默认开启 
return None
       该函数没有返回值会使用yield关键字抛出一个存放当前
   该层目录(root,dirs,files)的三元组,最终将所有目录层的的结果变为一个生成器
   root  所指的是当前正在遍历的这个文件夹的本身的地址
   dirs  是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)
   files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录)	

为了方便我们理解os.walk()最终抛出的数据的类型我们对它的生成器进行强制转换为list(),这样我们就可以看出其内部数据结构。

在我们的/mnt下有下面几个文件和目录



print(list(os.walk('/mnt',topdown = False)))

输出:

[('/mnt', ['dira', 'dirb'], ['file1', 'file2']), ('/mnt/dira', [], ['file_test_A']), ('/mnt/dirb', [], ['file_test_B'])]

这个列表(因为我们将生成器强制转化为列表)中的每一个元素都是一个元组,每一个元组都是都是一层目录,元组中的元素又代表了当前目录层的路径(根据赋给形参top的值来决定是绝对路径还是相对路径)、当前目录下有的文件目录、和当前目录下的文件。

当我们对生成器使用for循环时,会将每层一目录信息返回。

for info in os.walk('/mnt', topdown=True):
    print(info)
    print('***分隔符***')

输出:

('/mnt', ['dira', 'dirb'], ['file1', 'file2'])
***分隔符***
('/mnt/dira', [], ['file_test_A'])
***分隔符***
('/mnt/dirb', [], ['file_test_B'])
***分隔符***


注意:


这里抛出的值文件、路径和文件夹是分离的而不是在一起的 使用文件的据对路径一定要root+os.path.sep+filenames

下面两段代码就是我入过的坑

错误:

import os
def SearchAbsPath(dirname):
    dirname = os.path.abspath(dirname)
    filenames = list()
    for root,dirs,files in os.walk(dirname, topdown=False): #扫描一层目录
        for name in files:
            filenames.append(dirname+os.path.sep+name) #每一个文件的绝对路径放入列表
            print(dirname+os.path.sep+name)
    return filenames
SearchAbsPath('/mnt')

输出:

/mnt/file_test_A
/mnt/file_test_B
/mnt/__init__.py
/mnt/file1
/mnt/file2

正确:

import os
def SearchAbsPath(dirname):
    dirname = os.path.abspath(dirname)
    filenames = list()
    for root,dirs,files in os.walk(dirname, topdown=False): #扫描一层目录
        for name in files:
            filenames.append(root+os.path.sep+name) #每一个文件的绝对路径放入列表
            print(root+os.path.sep+name)
    return filenames
SearchAbsPath('.')

输出:

/mnt/dira/file_test_A
/mnt/dirb/file_test_B
/mnt/packeage/__init__.py
/mnt/file1
/mnt/file2


错误的代码,文件绝对路径=形参top的绝对路径+os.path.sep+文件名, 因此当我们们的top目录下还有多层目录时,我们水价格中间目录缺少,导致文件据对路径错误。


正确的代码,文件绝对路径 =root(在os.walk()传入的参数时绝对路径,root也就是绝对路径)+os.path.sep+文件名,不会缺失中间目录





版权声明:本文为m0_37717595原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。