Удаление файлов с байт-кодом

udalenie fajlov s bajt kodom Законченные системные программы

Модуль find из предыдущего раздела — не самый универсальный инструмент поиска строк из тех, что мы увидим далее, но несомненно является первым важным шагом. Он отбирает файлы, по которым затем можно реализовать поиск в сценарии автоматизации. Фактически наличие одной только операции отбора файлов из дерева каталогов достаточно для решения разнообразных задач системного администрирования.

Например, одна из типичных задач, которую мне приходится выполнять регулярно, заключается в удалении всех файлов с байт-кодом в дереве каталогов. Поскольку эти файлы не всегда являются переносимыми между основными версиями Python, их желательно удалять при подготовке программы к передаче пользователям, чтобы дать возможность интерпретатору самому создать новые файлы при первой же попытке импортировать модули. Теперь, когда мы получили богатый опыт использования функции os.walk, мы могли бы отказаться от услуг посредников и использовать ее непосредственно. В примере 6.14 представлен переносимый и универсальный инструмент командной строки, принимающий аргументы, обрабатывающий исключения и поддерживающий режим трассировки и простого поиска без удаления.

Пример 6.14. PP4E\Tools\cleanpyc.py

удаляет все файлы .pyc с байт-кодом в дереве каталогов: аргумент командной строки, если он указан, интерпретируется как корневой каталог, в противном случае корневым считается текущий рабочий каталог

import os, sys findonly = False rootdir = os.getcwd() if len(sys.argv) == 1 else sys.argv[1]

found = removed = 0

for (thisDirLevel, subsHere, filesHere) in os.walk(rootdir):

for filename in filesHere:

if filename.endswith(‘.pyc’):

fullname = os.path.join(thisDirLevel, filename) print(‘=>’, fullname) if not findonly:

try:

os.remove(fullname) removed += 1 except:

type, inst = sys.exc_info()[:2]

print(‘*’*4, ‘Failed:’, filename, type, inst) found += 1

print(‘Found’, found, ‘files, removed’, removed)

Если запустить этот сценарий, он выполнит обход дерева каталогов (CWDпо умолчанию, или дерева с корнем в каталоге, переданном в виде аргумента командной строки) и удалит все встретившиеся файлы с байт-кодом:

C:\\Examples\PP4E> Tools\cleanpyc.py

=> C:\Users\mark\Stuff\Books\4E\PP4E\dev\Examples\PP4E\__init__.pyc

=> C:\Users\mark\Stuff\Books\4E\PP4E\dev\Examples\PP4E\Preview\initdata.pyc

=> C:\Users\mark\Stuff\Books\4E\PP4E\dev\Examples\PP4E\Preview\make_db_file.pyc

=> C:\Users\mark\Stuff\Books\4E\PP4E\dev\Examples\PP4E\Preview\manager.pyc

=> C:\Users\mark\Stuff\Books\4E\PP4E\dev\Examples\PP4E\Preview\person.pyc

множество строк опущено

Found 24 files, removed 24

C:\\PP4E\Tools> cleanpyc.py .

=> .\find.pyc

=> .\visitor.pyc

=> .\__init__.pyc

Found 3 files, removed 3

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

Пример 6.15. PP4E\Tools\cleanpyc-find-shell.py

отыскивает и удаляет все файлы “*.pycс байт-кодом в дереве каталогов, имя которого передается в виде аргумента командной строки; предполагает наличие непереносимой Unix-подобной команды find

import os, sys

rundir = sys.argv[1]

if sys.platform[:3] == ‘win’:

findcmd = r’c:\cygwin\bin\find %s -name “*.pyc” -print’ % rundir else:

findcmd = ‘find %s -name “*.pyc” -print’ % rundir

print(findcmd)

count = 0

for fileline in os.popen(findcmd): # обход всех строк результата,

count += 1 # завершающихся символом \n

print(fileline, end=’’) os.remove(fileline.rstrip())

print(‘Removed %d .pyc files’ % count)

Этот сценарий удалит все файлы, имена которых возвращает команда оболочки:

C:\\PP4E\Tools> cleanpyc-find-shell.py .

c:\cygwin\bin\find . -name “*.pyc” -print

./find.pyc

./visitor.pyc

./__init__.pyc

Removed 3 .pyc files

В этом сценарии функция os.popen получает вывод программы find из оболочки Cygwin, установленной на одном из моих Windowsкомпьютеров, или от стандартной команды find, имеющейся в Linux. Он также абсолютно непереносим на компьютеры, работающие под управлением Windows, если на них не установлена Unix-подобная программа find, а ее нет ни на одном из моих личных компьютеров (не говоря уже о большинстве компьютеров в мире в целом). Кроме того, как мы уже знаем, запуск команд оболочки из сценариев наносит ущерб производительности, поскольку при этом приходится запускать новую независимую программу.

Мы можем значительно улучшить переносимость и производительность и при этом сохранить программный код простым, применив инструмент поиска, написанный нами на языке Python в предыдущем разделе. Новый сценарий приводится в примере 6.16.

Пример 6.16. PP4E\Tools\cleanpycfindpy.py

отыскивает и удаляет все файлы “*.pycс байт-кодом в дереве каталогов, имя которого передается в виде аргумента командной строки;

использует утилиту find, написанную на языке Python, за счет чего обеспечивается переносимость;

запустите этот сценарий, чтобы удалить файлы .pyc, скомпилированные старой версией Python;

import os, sys, find # here, gets Tools.find

count = 0

for filename in find.find(‘*.pyc’, sys.argv[1]):

count += 1

print(filename) os.remove(filename)

print(‘Removed %d .pyc files’ % count)

Как и прежде, этот сценарий удалит все файлы с байт-кодом в дереве каталогов с корнем, переданным в аргументе командной строки, но на этот раз наш сценарий может выполняться в любой системе, где установлен Python:

C:\\PP4E\Tools> cleanpyc-find-py.py .

.\find.pyc .\visitor.pyc .\__init__.pyc Removed 3 .pyc files

Этот сценарий переносим и позволяет избежать издержек, связанных с запуском внешних программ. Однако утилита find просто осуществляет поиск в дереве каталогов — она отбирает имена файлов, соответствующие шаблону, но не обращает внимания на их содержимое. Мы можем запрограммировать дополнительный поиск, используя результаты, полученные с помощью find, однако ручное управление позволит нам использовать процесс поиска более непосредственно. Как это можно сделать, демонстрируется в следующем разделе.

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

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