Теперь, после обобщения обхода деревьев и поиска, легко сделать следующий шаг и добавить отдельный, совершенно новый компонент автоматического редактирования файлов. В примере 6.19 приводится определение нового класса EditVisitor, который просто переопределяет метод visitmatch класса SearchVisitor, новая версия которого открывает найденный файл в текстовом редакторе. Да, это законченная программа — что-либо особое нужно делать только при обработке найденных файлов, и только это поведение должно обеспечиваться. Все остальное, касающееся логики обхода и поиска, остается неизменным и приобретается по наследству.
Пример 6.19. PP4E\Tools\visitor_edit.py
Порядок использования: “python …\Tools\visitor_edit.py string rootdir?”. Добавляет подкласс класса SearchVisitor, который автоматически запускает текстовый редактор. В процессе обхода автоматически открывает в текстовом редакторе файлы, содержащие искомую строку; в Windows можно также использовать editor=’edit’ или ‘notepad’; чтобы воспользоваться текстовым редактором, реализация которого будет представлена далее в книге, попробуйте r’python Gui\ TextEditor\textEditor.py’; при работе с некоторыми редакторами можно было бы передать команду перехода к первому совпадению с искомой строкой;
import os, sys
from visitor import SearchVisitor
class EditVisitor(SearchVisitor):
открывает для редактирования файлы, содержащие искомую строку и находящиеся в каталоге startDir и ниже
editor = r’C:\cygwin\bin\vim—nox.exe’ # у вас может быть другой редактор!
def visitmatch(self, fpathname, text):
os.system(‘%s %s’ % (self.editor, fpathname))
if __name__ == ‘__main__’:
visitor = EditVisitor(sys.argv[1])
visitor.run(‘.’ if len(sys.argv) < 3 else sys.argv[2])
print(‘Edited %d files, visited %d’ % (visitor.scount, visitor.fcount))
При использовании объекта EditVisitor текстовый редактор запускается посредством передачи командной строки функции os.system, которая обычно блокирует вызывающий программный код до момента, когда завершится порожденная программа. На моих машинах при каждом обнаружении сценарием совпадения во время обхода запускается текстовый редактор vi в том окне консоли, где был запущен сценарий. При выходе из редактора обход дерева возобновляется.
Найдем и отредактируем несколько файлов. При запуске этого файла как самостоятельного сценария мы передаем ему искомую строку в аргументе командной строки (здесь используется строка «mimetypes»). Корневой каталог всегда передается методу run как «.» (текущий рабочий каталог). Сообщения о состоянии обхода выводятся на консоль, но каждый файл, в котором обнаружено совпадение с искомой строкой, тут же автоматически открывается в текстовом редакторе. В данном случае редактор запускается восемь раз — попробуйте запустить этот сценарий в своем дереве каталогов и со своим редактором, чтобы лучше почувствовать, как он работает:
C:\…\PP4E\Tools> visitor_edit.py mimetypes C:\temp\PP3E\Examples C:\temp\PP3E\Examples …
1 => C:\temp\PP3E\Examples\README-root.txt C:\temp\PP3E\Examples\PP3E …
2 => C:\temp\PP3E\Examples\PP3E\echoEnvironment.pyw
3 => C:\temp\PP3E\Examples\PP3E\LaunchBrowser.pyw
4 => C:\temp\PP3E\Examples\PP3E\Launcher.py
5 => C:\temp\PP3E\Examples\PP3E\Launcher.pyc
Skipping C:\temp\PP3E\Examples\PP3E\Launcher.pyc
…множество строк опущено…
1427 => C:\temp\PP3E\Examples\PP3E\TempParts\lawnlake1-jan-03.jpg
Skipping C:\temp\PP3E\Examples\PP3E\TempParts\lawnlake1-jan-03.jpg
1428 => C:\temp\PP3E\Examples\PP3E\TempParts\part-001.txt
1429 => C:\temp\PP3E\Examples\PP3E\TempParts\part-002.html Edited 8 files, visited 1429
В итоге получился именно тот инструмент, который мне был нужен, чтобы упростить сопровождение дерева примеров книги. После значительных изменений, например задания имен совместно используемых модулей или файлов и каталогов, я запускаю этот сценарий в корневом каталоге дерева примеров с соответствующей строкой поиска и нужным образом редактирую все открывающиеся файлы. Мне все еще приходится вручную изменять файлы в редакторе, но это зачастую безопаснее, чем вслепую выполнять глобальную замену.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011