Запуск команд получения списка содержимого каталога с помощью os. popen

zapusk komand polucheniya spiska soderzhimogo kataloga s pomoshhju os popen Инструменты для работы с файлами и каталогами

Скажите-ка, как вы получали списки файлов в каталоге до того, как услышали о Python? Если у вас нет опыта работы с инструментами командной строки, ответ может быть следующим: «Ну, я запускал в Windows проводник и щелкал, куда нужно». Но здесь у нас речь идет о механизмах, менее ориентированных на графический интерфейс, то есть о механизмах командной строки.

Для получения списков файлов в Unix обычно используется команда ls; в Windows списки можно создавать вводом dir в окне консоли MSDOS.

Поскольку сценарии Python могут выполнить любую команду оболочки с помощью os.popen, они являются самым универсальным способом получения содержимого каталога из программ на языке Python. Мы уже встречались с функцией os.popen в предыдущей главе — она выполняет команду оболочки и возвращает объект файла, из которого можно прочесть вывод команды. Для иллюстрации допустим сначала, что имеется следующая структура каталогов — на моем ноутбуке с Windows есть обе команды, dir и Unix-подобная ls из Cygwin:

c:\temp> dir /B

parts

PP3E

random.bin

spam.txt temp.bin temp.txt

c:\temp> c:\cygwin\bin\ls

PP3E parts random.bin spam.txt temp.bin temp.txt

c:\temp> c:\cygwin\bin\ls parts

part0001 part0002 part0003 part0004

Имена parts и PP3E являются здесь подкаталогами, вложенным в каталог C:\temp (последний из них является копией дерева каталогов с примерами для предыдущего издания книги, часть из которых я использовал в этом издании). Теперь мы знаем, что сценарии могут получать списки имен файлов и каталогов на этом уровне, просто запуская специфическую для платформы команду и читая полученный вывод (текст, обычно выводимый в окно консоли):

C:\temp> python

>  >> import os

>  >> os.popen(‘dir /B’).readlines()

[‘parts\n’, ‘PP3E\n’, ‘random.bin\n’, ‘spam.txt\n’, ‘temp.bin\n’, ‘temp.txt\n’]

Строки, возвращаемые командой оболочки, содержат замыкающий символ конца строки, но его легко можно отсечь. Кроме того, функция os.popen возвращает итератор, точно такой же, как итератор объектов файлов:

>  >> for line in os.popen(‘dir /B’):

print(line[:-1])

parts

PP3E

random.bin

spam.txt temp.bin temp.txt

>  >> lines = [line[:-1] for line in os.popen(‘dir /B’)]

>  >> lines

[‘parts’, ‘PP3E’, ‘random.bin’, ‘spam.txt’, ‘temp.bin’, ‘temp.txt’]

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

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

>  >> os.popen(‘dir *.bin /B’).readlines()

[‘random.bin\n’, ‘temp.bin\n’]

>  >> os.popen(r’c:\cygwin\bin\ls *.bin’).readlines()

[‘random.bin\n’, ‘temp.bin\n’]

>  >> list(os.popen(r’dir parts /B’))

[‘part0001\n’, ‘part0002\n’, ‘part0003\n’, ‘part0004\n’]

>  >> [fname for fname in os.popen(r’c:\cygwin\bin\ls parts’)]

[‘part0001\n’, ‘part0002\n’, ‘part0003\n’, ‘part0004\n’]

Эти вызовы используют универсальные инструменты и все действуют, как было заявлено. Однако выше отмечалось, что недостатками os.popen являются необходимость использования команд оболочки, специфических для платформы, и потеря производительности при запуске независимых программ. На практике различные инструменты могут возвращать различные результаты:

>  >> list(os.popen(r’dir parts\part* /B’))

[‘part0001\n’, ‘part0002\n’, ‘part0003\n’, ‘part0004\n’]

>>> 

>  >> list(os.popen(r’c:\cygwin\bin\ls parts/part*’))

[‘parts/part0001\n’, ‘parts/part0002\n’, ‘parts/part0003\n’, ‘parts/part0004\n’]

Следующие два альтернативных приема проявляют себя лучше в обоих отношениях.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий