Для проверки способности графического интерфейса запускать сценарии командной строки нам, конечно же, необходимо создать несколько таких сценариев. Следующие два сценария, находящиеся в самом низу иерархии, реализуют архивацию текстовых файлов, используя системные инструменты и приемы, описанные во второй части книги. Первый сценарий, представленный в примере 10.7, просто объединяет содержимое нескольких текстовых файлов в один файл, добавляя предопределенные строки-разделители между ними.
Пример 10.7. PP4E\Gui\ShellGui\packer.py
# упаковывает текстовые файлы в единый файл, добавляя строки-разделители
# (простейшая архивация)
import sys, glob
marker = ‘:’ * 20 + ‘textpak=>’ # надеемся, что это уникальная строка
def pack(ofile, ifiles):
output = open(ofile, ‘w’)
for name in ifiles:
print(‘packing:’, name)
input = open(name, ‘r’).read() # открыть следующий входной файл
if input[-1] != ‘\n’: input += ‘\n’ # гарантировать наличие \n в конце output.write(marker + name + ‘\n’) # записать строку-разделитель output.write(input) # и содержимое входного файла
if __name__ == ‘__main__’:
ifiles = []
for patt in sys.argv[2:]: # в Windows не выполняется автоматическая
ifiles += glob.glob(patt) # подстановка по шаблону
pack(sys.argv[1], ifiles) # упаковать файлы, перечисленные # в командной строке
Второй сценарий, который приводится в примере 10.8, сканирует файлы архивов, созданные первым сценарием, и восстанавливает оригинальные файлы.
Пример 10.8. PP4E\Gui\ShellGui\unpacker.py
# распаковывает архивы, созданные сценарием packer.py
# (простейшие архивы текстовых файлов)
import sys
from packer import marker # использовать общую строку-разделитель
mlen = len(marker) # имена файлов следуют за строкой-разделителем
def unpack(ifile, prefix=’new-’):
for line in open(ifile): # по всем строкам входного файла
if line[:mlen] != marker:
output.write(line) # действительные строки записать
else:
name = prefix + line[mlen:-1] # или создать новый выходной файл print(‘creating:’, name) output = open(name, ‘w’)
if __name__ == ‘__main__’: unpack(sys.argv[1])
Это чрезвычайно простые сценарии, и в этой части книги предполагается, что вы уже прочитали главы, посвященные системным инструментам, поэтому мы не будем вдаваться в подробности их реализации. Варианты этих сценариев появились еще в первом издании этой книги, в 1996 году. Я пользовался ими на заре моей карьеры программиста на языке Python для архивации файлов, еще до того, как на всех моих компьютерах появились такие инструменты, как tar и zip (и еще до того, как в стандартной библиотеке Python появились модули поддержки tar и zip). Принцип действия этих сценариев чрезвычайно прост. Возьмем следующие три текстовых файла:
C:\…\PP4E\Gui\ShellGui> type spam.txt
spam
Spam
SPAM
C:\…\PP4E\Gui\ShellGui> type eggs.txt eggs
C:\…\PP4E\Gui\ShellGui> type ham.txt h
a m
Если запустить сценарий packer из командной строки, он объединит эти файлы в один общий файл, а сценарий unpacker извлечет их оттуда. Сценарий packer должен предусматривать обработку шаблонов имен файлов, потому что командная оболочка в Windows не выполняет автоматическое расширение шаблонов:
C:\…\PP4E\Gui\ShellGui> packer.py packed.txt *.txt
packing: eggs.txt
packing: ham.txt
packing: spam.txt
C:\…\PP4E\Gui\ShellGui> unpacker.py packed.txt
creating: new-eggs.txt
creating: new-ham.txt
creating: new—spam.txt
Файлы, извлекаемые из архива, по умолчанию получают уникальные имена (с дополнительным префиксом, чтобы избежать случайного затирания оригинальных файлов, что особенно важно на этапе тестирования), и вы получаете то, что было упаковано в архив:
C:\…\PP4E\Gui\ShellGui> type new-spam.txt spam
Spam
SPAM
C:\…\PP4E\Gui\ShellGui> type packed.txt
::::::::::::::::::::textpak=>eggs.txt
eggs
::::::::::::::::::::textpak=>ham.txt h
a
m
::::::::::::::::::::textpak=>spam.txt
spam
Spam
SPAM
Эти сценарии не предназначены для архивации двоичных файлов, не выполняют сжатие или что-то еще, а служат лишь иллюстрацией сценариев командной строки с обязательными аргументами командной строки. Они могут использоваться самостоятельно, как было показано выше (и запускаться с помощью таких инструментов в языке Python, как os.popen и subprocess), или как модули, которые могут импортироваться и вызываться другими программами. В нашем графическом интерфейсе мы будем использовать второй, более прямой интерфейс вызовов.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011