Я правильно понимаю os.walk?

Цикл для root, dir, file inos.walk(startdir) работает через эти шаги?

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

get root of start dir : C:\dir1\dir2\startdir

get folders in C:\dir1\dir2\startdir and return list of folders "dirlist"

get files in first dirlist item and return list of files "filelist" as the first item of a list of filelists.

move to second item in dirlist and return list of files in this folder "filelist2" as the second item of a list of filelists. etc.

move to next root in foldertree and start from 2. etc.

Правильно? Или он сначала получает все корни, потом все dirs, а все файлы третьи?

 Baf13 июн. 2012 г., 14:40
почему я получил минус 1 за это? я сделал что-то неправильно?

Ответы на вопрос(5)

Minimal runnable example

Вот как мне нравится учить вещи:

mkdir root
cd root
mkdir \
  d0 \
  d1 \
  d0/d0_d1
touch \
   f0 \
   d0/d0_f0 \
   d0/d0_f1 \
   d0/d0_d1/d0_d1_f0
tree

Выход:

.
├── d0
│   ├── d0_d1
│   │   └── d0_d1_f0
│   ├── d0_f0
│   └── d0_f1
├── d1
└── f0

main.py

#!/usr/bin/env python3
import os
for path, dirnames, filenames in os.walk('root'):
    print('{} {} {}'.format(repr(path), repr(dirnames), repr(filenames)))

Выход:

'root' ['d0', 'd1'] ['f0']
'root/d0' ['d0_d1'] ['d0_f0', 'd0_f1']
'root/d0/d0_d1' [] ['d0_d1_f0']
'root/d1' [] []

Это все проясняет:

path is the root directory of each step dirnames is a list of directory basenames in each path filenames is a list of file basenames in each path

Протестировано на Ubuntu 16.04, Python 3.5.2.

Modifying dirnames changes the tree recursion order

Это в основном единственное, что вы должны иметь в виду.

Например, если вы делаете следующие операции наdirnames, это влияет на обход:

sort filter

Walk file or directory

Если вход для traverse является файлом или каталогом, вы можете обработать его следующим образом:

#!/usr/bin/env python3

import os
import sys

def walk_file_or_dir(root):
    if os.path.isfile(root):
        dirname, basename = os.path.split(root)
        yield dirname, [], [basename]
    else:
        for path, dirnames, filenames in os.walk(root):
            yield path, dirnames, filenames

for path, dirnames, filenames in walk_file_or_dir(sys.argv[1]):
    print(path, dirnames, filenames)

os.walk () сгенерирует набор путей, папок, файлов, присутствующих в указанном пути, и продолжит обход подпапок.

import os.path
path=input(" enter the path\n")
for path,subdir,files in os.walk(path):
   for name in subdir:
       print os.path.join(path,name) # will print path of directories
   for name in files:    
       print os.path.join(path,name) # will print path of files

это сгенерирует пути ко всем подкаталогам, файлам и файлам в подкаталогах

Решение Вопроса

os.walk возвращает генератор, который создает кортеж значений (current_path, каталоги в current_path, файлы в current_path).

Каждый раз, когда вызывается генератор, он будет рекурсивно следовать за каждым каталогом до тех пор, пока из начального каталога, к которому был вызван обход, не будет доступно никаких дополнительных подкаталогов.

В качестве таких,

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
 Baf13 июн. 2012 г., 15:39
спасибо также Самир!
 Baf13 июн. 2012 г., 15:40
Кстати, все вышеперечисленные ответы стоят тега ответа, но я могу пометить только один из постов как ответ! плохо, или есть способ пометить несколько сообщений как ответ?
 Baf13 июн. 2012 г., 15:41
о, и еще, почему вы импортируете os и os.path? Не включен ли os.path при импорте os?
 Baf13 июн. 2012 г., 15:39
Мне нравится решение os.path, поэтому os.path всегда будет соответствовать каталогу, в котором находится os.walk во время этой итерации?
 13 июн. 2012 г., 21:16
модуль os это зверь 23к строк, но даimport os.path не требуется, хотя я помню, что однажды у меня была проблема, но я не могу вспомнить, что это было, в любом случае os.path - самый безопасный способ справиться с путямиos.path.join он будет автоматически генерировать соответствующийjoin в любой операционной системе Windows знает, что они должны «\»; и сбежал в * nix, он знает, что они должны быть/ и он знает, когда объединять каталоги или просто файлы, это довольно умно :)

os.walk работает немного иначе, чем выше. По сути, он возвращает кортежи (путь, каталоги, файлы). Чтобы увидеть это, попробуйте следующее:

import pprint
import os
pp=pprint.PrettyPrinter(indent=4)
for dir_tuple in os.walk("/root"):
    pp.pprint(dir_tuple)

... вы увидите, что каждая итерация цикла будет печатать имя каталога, список имен любых каталогов, находящихся непосредственно в этом каталоге, и другой список всех файлов в этом каталоге. Затем os.walk будет вводить каждый каталог в список подкаталогов и делать то же самое, пока не будут пройдены все подкаталоги исходного корня. Это может помочь немного узнать о рекурсии, чтобы понять, как это работает.

 Baf13 июн. 2012 г., 14:45
я читаю рекурсию Так что в цикле for я делаю над элементами кортежа, если я использую оператор if для проверки файлов, он будет проверять только оператор
 Baf13 июн. 2012 г., 15:50
также этот отпечаток довольно опрятен, спасибо за это!
 Baf13 июн. 2012 г., 14:39
Большое спасибо, Алекс!

os.walk () работает вместе с некоторыми объяснениями, используя несколькоОперационные системы функции.

Первое замечание, чтоos.walk () возвращаетсяthree элементы, корневой каталог, список каталогов (dirs) сразу под текущим корнем и списком файлов, найденных в этих каталогах.документация даст вам больше информации.

dirs будет содержать список каталогов чуть ниже root, а файлы будут содержать список всех файлов, найденных в этих каталогах. В следующей итерации каждый каталог из тех, что в предыдущемdirs список возьмет на себя рольroot в свою очередь, и поиск продолжится оттуда, спускаясь по уровню только после поиска текущего уровня.

Пример кода: это будет искать, считать и распечатывать имена.jpg  а также.gif файлы ниже указанной директории поиска (ваш корень). Он также используетos.path.splitext () функция для отделения базы файла от его расширения иos.path.join () функция, чтобы дать вам полное имя, включая путь к найденным файлам изображений.

import os

searchdir = r'C:\your_root_dir'  # your search starts in this directory (your root) 

count = 0
for root, dirs, files in os.walk(searchdir):
    for name in files:
        (base, ext) = os.path.splitext(name) # split base and extension
        if ext in ('.jpg', '.gif'):          # check the extension
            count += 1
            full_name = os.path.join(root, name) # create full path
            print(full_name)

print('\ntotal number of .jpg and .gif files found: %d' % count)
 06 авг. 2015 г., 01:30
На всякий случай, если кто-нибудь еще наткнется на это после поиска os.walk и & quot; в ширину & quot; - вышеуказанная информация неверна. os.walk (по крайней мере, в python 2.6 и 2.7) выполняет обход в глубину, а НЕ обход в ширину. Точный порядок, в котором предметы выдаются, зависит от параметра topdown - если topdown имеет значение True (по умолчанию), то он выполняет предварительный порядок обхода в глубину (en.wikipedia.org/wiki/File:Sorted_binary_tree_preorder.svg), в то время как если значение равно False, оно выполняет обход глубины после заказа (en.wikipedia.org/wiki/File:Sorted_binary_tree_postorder.svg).
 Baf13 июн. 2012 г., 14:46
спасибо Левон очень тщательно! Вы, ребята, переполняетесь стеком!

Ваш ответ на вопрос