Переопределение os.walk для возврата объекта генератора в качестве третьего элемента
При проверке эффективности os.walk
, Я создал 6,00,000
файлы со строкой Hello <number>
(где число - это просто число, указывающее номер файла в каталоге), например, содержимое файлов в каталоге будет выглядеть так:
File Name | Contents
1.txt | Hello 1
2.txt | Hello 2
.
.
600000.txt|Hello 600000
Теперь я запустил следующий код:-
a= os.walk(os.path.join(os.getcwd(),'too_many_same_type_files')) ## Here, I am just passing the actual path where those 6,00,000 txt files are present
print a.next()
Проблема, которую я чувствовал, состояла в том, что a.next()
занимает слишком много времени и памяти, потому что третий пункт, который a.next()
вернул бы список файлов в каталоге (который имеет 600000 элементов). Итак, я пытаюсь найти способ уменьшить сложность пространства (по крайней мере) путем a.next()
вернуть объект генератора в качестве 3-го элемента кортежа вместо списка имен файлов.
Было бы хорошей идеей уменьшить сложность пространства?
3 ответа
Как уже упоминалось, 600000 файлов в каталоге - плохая идея. Сначала я думал, что на самом деле нет способа сделать это из-за того, как вы получаете доступ к списку файлов, но оказывается, что я ошибаюсь. Вы можете использовать следующие шаги для достижения того, что вы хотите:
Использовать подпроцесс или
os.system
звонитьls
или жеdir
(в какой бы ОС вы ни находились). Направьте вывод этой команды во временный файл (скажем,/tmp/myfiles
или что-то. В Python есть модуль, который может вернуть вам новыйtmp
файл).Откройте этот файл для чтения в Python.
Файловые объекты являются итеративными и будут возвращать каждую строку, поэтому, если у вас есть только имена файлов, все будет в порядке.
Это хорошая идея, именно так работает базовый C API!
Если вы можете получить доступ к readdir, вы можете сделать это: к сожалению, это не предоставляется напрямую Python.
Этот вопрос показывает два подхода (оба с недостатками).
Более чистым подходом было бы написать модуль на C, чтобы показать желаемую функциональность.
os.walk
звонки listdir()
под капотом, чтобы извлечь содержимое корневого каталога, затем приступает к разделению возвращенного списка элементов на dirs и non-dirs.
Чтобы достичь того, что вы хотите, вам нужно копать намного ниже и реализовать не только свою собственную версию walk()
но и альтернатива listdir()
который возвращает генератор. Обратите внимание, что даже тогда вы не сможете предоставить независимые генераторы для каталогов и файлов, если вы не сделаете два отдельных вызова для измененных listdir()
и фильтровать результаты на лету.
Как предложено Свеном в комментариях выше, возможно, было бы лучше решить реальную проблему (слишком много файлов в директории), а не перерабатывать решение.