Подтвердить что ты не робот

Итерация через каталоги с помощью Python

Мне нужно выполнить итерацию через подкаталоги данного каталога и поиск файлов. Если я получаю файл, я должен его открыть и изменить содержимое и заменить его на собственные строки.

Я пробовал это:

import os

rootdir ='C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        f=open(file,'r')
        lines=f.readlines()
        f.close()
        f=open(file,'w')
        for line in lines:
            newline = "No you are not"
            f.write(newline)
        f.close()

но я получаю сообщение об ошибке. Что я делаю не так?

4b9b3361

Ответ 1

Фактическая прогулка по каталогам работает так, как вы ее закодировали. Если вы замените содержимое внутреннего цикла простым инструктором print, вы увидите, что каждый файл найден:

import os
rootdir = 'C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        print os.path.join(subdir, file)

Если вы все еще получаете ошибки при запуске вышеуказанного, предоставьте сообщение об ошибке.

Ответ 2

Другой способ вернуть все файлы в подкаталогах - использовать модуль pathlib, представленный в Python 3.4, который обеспечивает объектно-ориентированный подход к обработке путей в файловой системе (Pathlib также доступен в Python 2.7 через модуль pathlib2 в PyPi):

from pathlib import Path

rootdir = Path('C:/Users/sid/Desktop/test')
# Return a list of regular files only, not directories
file_list = [f for f in rootdir.glob('**/*') if f.is_file()]

# For absolute paths instead of relative the current dir
file_list = [f for f in rootdir.resolve().glob('**/*') if f.is_file()]

Начиная с Python 3.5, модуль glob также поддерживает рекурсивный поиск файлов:

import os
from glob import iglob

rootdir_glob = 'C:/Users/sid/Desktop/test/**/*' # Note the added asterisks
# This will return absolute paths
file_list = [f for f in iglob('**/*', recursive=True) if os.path.isfile(f)]

file_list любого из вышеперечисленных подходов может быть повторен без необходимости во вложенном цикле:

for f in file_list:
    print(f) # Replace with desired operations

Ответ 3

Начиная с 2019 года, glob.iglob(path/**, recursive=True) представляется наиболее питоническим решением, т.е.

import glob, os

for filename in glob.iglob('/pardadox-music/**', recursive=True):
    if os.path.isfile(filename): # filter dirs
        print(filename)

Выход:

/pardadox-music/modules/her1.mod
/pardadox-music/modules/her2.mod
...

Примечания:
1 - glob.iglob

glob.iglob(pathname, recursive=False)

Вернуть итератор, который выдает те же значения, что и glob(), фактически не сохраняя их все одновременно.

2 - Если рекурсивным является True, шаблон '**' будет соответствовать любым файлам и ноль или более directories и subdirectories.

3 - Если каталог содержит файлы, начинающиеся с ., они не будут сопоставлены по умолчанию. Например, рассмотрим каталог, содержащий card.gif и .card.gif:

>>> import glob. 
>>> glob.glob('*.gif')

['card.gif']

       

glob.glob('.c*')

  

[ '.Card.gif']

,

Ответ 4

for subdir, dirs, files in os.walk(rootdir):
    os.chdir(rootdir)  # >>>>>>>>>>>>>>>>>>>>>>>>>> Pls add this line and try.
    for file in files:
        print file
        f=open(file,'r')
        lines=f.readlines()