Я правильно понимаю os.walk?
Этот цикл для root, dir, файла в os.walk(startdir)
работает через эти шаги?
for root in os.walk(startdir)
for dir in root
for files in dir
-
получить root из начального каталога: C:\dir1\dir2\startdir
-
получить папки в C:\dir1\dir2\startdir и вернуть список папок "dirlist"
-
получить файлы в первом элементе dirlist и вернуть список файлов "filelist" в качестве первого элемента списка файловых списков.
-
перейдите во второй элемент в dirlist и верните список файлов в этой папке "filelist2" как второй элемент списка файловых списков. и т.п.
-
перейдите к следующему корню в папке и начните с 2. и т.д.
Правильно? Или он просто получает все корни в первую очередь, тогда все диски второго и все файлы третьи?
Ответы
Ответ 1
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
Ответ 2
Простыми словами 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
это приведет к генерации путей всех подкаталогов, файлов и файлов в подкаталогах
Ответ 3
Вот краткий пример того, как os.walk() работает вместе с некоторыми объяснениями, используя несколько функций os.
Прежде всего обратите внимание, что os.walk() возвращает три элемента, корневой каталог, список каталогов (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)
Ответ 4
Пример минимального запуска
Вот как мне нравится учить вещи:
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
является корневым каталогом каждого шага
dirnames
- это список базовых имен каталогов в каждом path
filenames
- это список базовых имен файлов в каждом path
Протестировано на Ubuntu 16.04, Python 3.5.2.
Модификация dirnames
изменяет рекурсию дерева
По сути, это единственное, что вы должны иметь в виду.
Например, если вы выполните следующие операции с dirnames
, это повлияет на обход:
Пройдите файл или каталог
Если вход для перемещения является файлом или каталогом, вы можете обработать его следующим образом:
#!/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)
Ответ 5
os.walk работает немного иначе, чем выше. В основном, он возвращает кортежи (путь, каталоги, файлы). Чтобы увидеть это, попробуйте следующее:
import pprint
import os
pp=pprint.PrettyPrinter(indent=4)
for dir_tuple in os.walk("/root"):
pp.pprint(dir_tuple)
... вы увидите, что каждая итерация цикла будет печатать имя каталога, список имен любых каталогов непосредственно внутри этого каталога и другой список всех файлов в этом каталоге. Затем os.walk будет вводить каждый каталог в список подкаталогов и делать то же самое, пока не будут пройдены все подкаталоги исходного корня. Это может помочь немного узнать о рекурсии, чтобы понять, как это работает.