Мы отложим дальнейшее обсуждение Юникода, пока нам не представится возможность увидеть его в прикладном контексте и в практических программах. Более фундаментальное освещение поддержки текстовых и двоичных данных Юникода в строках и файлах вы найдете в четвертом издании книги «Изучаем Python». Эта книга официально посвящена основам языка, что предполагает углубленное рассмотрение тем и позволило отвести этой теме отдельную главу, занимающую 45 страниц.
Основы операций с файлами
Помимо обработки строк, сценарий more.py также использует файлы - он открывает внешний файл, имя которого задается в командной строке, с помощью встроенной функции open, и целиком считывает его в память с помощью метода read объекта файла. Поскольку объекты файлов, возвращаемые функцией open, являются составной частью самого базового языка Python, я могу предположить, что вы хотя бы бегло знакомы с ними. Но в случае, если эта глава попалась вам в самом начале изучения Python, подскажу, что следующие вызовы загружают в строку содержимое файла, загружают в строку набор байтов фиксированной длины, загружают содержимое файла в список строк и загружают в строку очередную строку файла, соответственно:
open(‘file’).read() # читает весь файл в строку
open(‘file’).read(N) # читает следующие N байтов в строку
open(‘file’).readlines() # читает весь файл в массив строк
open(‘file’).readline() # читает следующую строку, до символа ‘\n’
Как мы скоро увидим, эти вызовы можно также применять в Python к командам оболочки, чтобы прочитать их вывод. У объектов файлов есть также методы write, которые посылают строки в соответствующий файл. Более глубоко темы, связанные с файлами, раскрываются в главе 4, однако сами операции вывода данных в файл и чтения их обратно в языке Python реализуются очень просто:
>>> file = open('spam.txt', 'w') # создать файл spam.txt
>>> file.write(('spam' * 5) + '\n') # записать текст: вернет
21 # число записанных символов >>> file.close()
>>> file = open('spam.txt') # или open(‘spam.txt’).read()
>>> text = file.read() # прочитать в строку
>>> text
‘spamspamspamspamspam\n’
Два способа использования программ
Последние несколько строк в сценарии more.py из примера 2.1 знакомят нас с одним из первых важных понятий в программировании инструментов командной строки. Они настраивают файл так, чтобы его можно было использовать двумя способами: как сценарий или как библиотеку.
Напомню, что в каждом модуле Python доступна встроенная переменная__name__, в которую интерпретатор Python записывает значение
__main__, только если файл выполняется как программа, а не импортируется в качестве библиотеки. Благодаря этому функция more в этом файле автоматически выполняется в последней строке файла, когда сценарий запускается, как самостоятельная программа, а не импортируется в какое-либо другое место. Этот простой прием является ключом к созданию многократно используемых сценариев: благодаря реализации логики программы в виде функции, а не в виде программного кода верхнего уровня, ее можно импортировать и повторно использовать в других сценариях.
В результате появляется возможность запускать more.py отдельно или импортировать его и вызывать функцию more из любого другого места. При запуске файла как самостоятельной программы мы передаем ей в командной строке имя файла, который нужно прочесть и выводить постранично: в следующей главе будет полностью описано, как слова, вводимые в команде для запуска программы, появляются во встроенном списке sys.argv. Ниже приводится пример запуска файла сценария для постраничного вывода самого себя (эта команда должна выполняться в каталоге PP4E\System, иначе входной файл не будет найден; причина этого будет пояснена позднее):
C:\...\PP4E\System> python more.py more.py
разбивает строку или текстовый файл на страницы для интерактивного просмотра def more(text, numlines=15):
lines = text.splitlines() # подобно split(‘\n’), но без ‘’ в конце
while lines:
chunk = lines[:numlines] lines = lines[numlines:] for line in chunk: print(line)
More?y
if lines and input(‘More?’) not in [‘y’, ‘Y’]: break
if__name__== ‘__main__’:
import sys # если запускается как сценарий
more(open(sys.argv[1]).read(), 10) # отобразить постранично содержимое