1. ホーム
  2. python

[解決済み] os.walkの理解は正しいですか?

2022-03-04 19:31:01

質問

のroot, dir, fileのループは、root, dir, fileのループと同じです。 os.walk(startdir) は、これらのステップを経て動作するのですね。

for root in os.walk(startdir) 
    for dir in root 
        for files in dir

  1. get root of start dir : C:\dir1dir2startdir

  2. C:\dir1dir2startdir 内のフォルダーを取得し、フォルダーのリスト "dirlist" を返します。

  3. dirlist の最初の項目にあるファイルを取得し、ファイルのリスト "filelist"として返します。

  4. dirlistの2番目の項目に移動し、このフォルダ内のファイルのリスト "filelist2" をファイルリストの2番目の項目として返します。

  5. フォルダツリーの次のルートに移動し、2 から開始します。

でしょ?それとも、最初にすべてのルートを取得し、次にすべてのディレクトリを取得し、最後にすべてのファイルを取得するのでしょうか?

解決方法は?

os.walk は、値のタプル(current_path, current_pathのディレクトリ, current_pathのファイル)を作成するジェネレータを返します。

ジェネレータが呼ばれるたびに、walk が呼び出された最初のディレクトリからさらにサブディレクトリが利用できなくなるまで、各ディレクトリを再帰的にたどります。

このように

os.walk('C:\dir1\dir2\startdir').next()[0] # returns 'C:\dir1\dir2\startdir'
os.walk('C:\dir1\dir2\startdir').next()[1] # returns all the dirs in 'C:\dir1\dir2\startdir'
os.walk('C:\dir1\dir2\startdir').next()[2] # returns all the files in 'C:\dir1\dir2\startdir'

だから

import os.path
....
for path, directories, files in os.walk('C:\dir1\dir2\startdir'):
     if file in files:
          print('found %s' % os.path.join(path, file))

またはこれ

def search_file(directory = None, file = None):
    assert os.path.isdir(directory)
    for cur_path, directories, files in os.walk(directory):
        if file in files:
            return os.path.join(directory, cur_path, file)
    return None

または、ファイルを探したい場合は、このようにすることができます。

import os
def search_file(directory = None, file = None):
    assert os.path.isdir(directory)
    current_path, directories, files = os.walk(directory).next()
    if file in files:
        return os.path.join(directory, file)
    elif directories == '':
        return None
    else:
        for new_directory in directories:
            result = search_file(directory = os.path.join(directory, new_directory), file = file)
            if result:
                return result
        return None