Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 92
Текст из файла (страница 92)
При необходимости получить более сложноеформатирование совсем не обязательно использовать эту возможность. Вместо этого можно сконструировать строку заранее или прибегнуть к помощиинструментов форматирования, с которыми мы встречались в главе 7, внутривызова функции print, и вывести сконструированную строку единственнымвызовом print:>>> text = ‘%s: %-.4f, %05d’ % (‘Result’, 3.14159, 42)>>> print(text)Result: 3.1416, 00042366Глава 11. Присваивание, выражения и print>>> print(‘%s: %-.4f, %05d’ % (‘Result’, 3.14159, 42))Result: 3.1416, 00042Как мы увидим в следующем разделе, практически все, что было сказаноо функции print в Python 3.0, точно так же применимо и к инструкции printв версии 2.6, особенно если учесть, что функция задумывалась как дальнейшее развитие и улучшение поддержки операции вывода в 2.6.Инструкция print в Python 2.6Как уже упоминалось выше, операция вывода в Python 2.6 реализована в видеинструкции с уникальным и весьма специфическим синтаксисом, а не в видевстроенной функции.
На практике же печать? организованная в 2.6, являетсявариацией на ту же тему – за исключением строк-разделителей (которые поддерживаются в версии 3.0 и не поддерживаются в версии 2.6), для всех остальных возможностей функции print в версии 3.0 имеют прямые аналоги в инструкции print в версии 2.6.Формы инструкцииВ табл. 11.5 перечислены формы инструкции print в ������������������������Python������������������ 2.6 и эквивалентные им вызовы функции print в Python 3.0.
Обратите внимание, что запятаяв инструкции print имеет важное значение – она отделяет объекты, которыетребуется вывести, а завершающая запятая подавляет вывод символа концастроки, который обычно выводится в конце строки текста (не путайте с синтаксисом кортежей!). Синтаксическая конструкция >> обычно используетсякак оператор побитового сдвига вправо, однако он может использоваться и винструкции print, чтобы определить поток вывода, отличный от sys.stdout, который используется по умолчанию.Таблица 11.5. Перечень форм инструкции printИнструкция printв Python 2.6Эквивалентв Python 3.0Интерпретацияprint x, yprint(x, y)Вывод объектов в sys.stdout;добавляет пробел междуобъектами и символ концастрокиprint x, y,print(x, y, end=’’)То же самое, только на этотраз символ конца строки недобавляетсяprint >> afile, x, yprint(x, y, file=afile)Текст передается методуmyfile.write, а не sys.stdout.writeИнструкция print в действииХотя синтаксис инструкции print в �����������������������������������������Python����������������������������������� 2.6 отличается от синтаксиса функции print в Python 3.0, тем не менее она точно так же проста в использовании.Давайте рассмотрим несколько простых примеров.
По умолчанию инструкция367Операция printprint в версии 2.6 добавляет пробел между элементами, отделенными запятыми, и символ конца строки в конце текущей строки вывода:C:\misc> c:\python26\python>>>>>> x = ‘a’>>> y = ‘b’>>> print x, ya bТакое форматирование – всего лишь значение по умолчанию, которое можноиспользовать или нет. Чтобы подавить вывод символа конца строки (и позднеепродолжить вывод текста в текущую строку), инструкцию print следует завершать символом запятой, как показано во второй строке табл. 11.5 (ниже приводятся две инструкции в одной строке, разделенные точкой с запятой):>>> print x, y,; print x, ya b a bЧтобы подавить вывод пробела между элементами, следует производить выводне таким способом – вместо этого нужно самостоятельно собрать строку с помощью операции конкатенации и форматирования, о которых рассказывалосьв главе 7, и вывести эту строку:>>> print x + yab>>> print ‘%s...%s’ % (x, y)a...bКак видно из примеров, если не считать специального синтаксиса задания различных режимов вывода, инструкция print в версии 2.6 почти так же простав использовании, как и функция print в версии 3.0.
В следующем разделе описывается способ перенаправления вывода в файл с помощью инструкции printв 2.6.Перенаправление потока вывода в инструкции printВ обеих версиях, ��������������������������������������������������������Python�������������������������������������������������� 3.0 и 2.6, выводимый текст по умолчанию передается в поток стандартного вывода. Однако достаточно часто возникает необходимость вывести текст в какое-нибудь другое место, например в файл, чтобысохранить результаты для последующего использования или для нужд тестирования.
Подобное перенаправление вывода можно организовать на уровнесистемной командной оболочки, за пределами интерпретатора, однако перенаправление внутри сценария реализуется ничуть не сложнее.Программа «hello world» на языке PythonНачнем с привычного (и обыденного) теста языка программирования – с программы «hello world».
Чтобы вывести сообщение «hello world» в программе наязыке Python, достаточно просто напечатать строку:>>> print(‘hello world’)hello world# Вызов строкового объекта в 3.0>>> print ‘hello world’hello world# Вызов строкового объекта в 2.6368Глава 11. Присваивание, выражения и printПоскольку результаты выражений в интерактивной оболочке выводятся автоматически, вы можете даже не использовать инструкцию print – просто введите выражение, которое требуется вывести, и результат его вычисления немедленно будет выведен:>>> ‘hello world’‘hello world’# Интерактивная оболочка выводит результат автоматическиЭтот фрагмент трудно назвать примером программистского мастерства, темне менее он наглядно демонстрирует особенности поведения операции вывода.В действительности инструкция print – это всего лишь эргономичная особенность языка Python, – она обеспечивает простой интерфейс к объекту sys�����.����stdout, добавляя незначительный объем форматирования.
Фактически если вамнравится идти более трудным путем, вы можете запрограммировать вывод таким способом:>>> import sys# Вывод более сложным способом>>> sys.stdout.write(‘hello world\n’)hello worldВ этом фрагменте явно вызывается метод write объекта sys.stdout – атрибут,предустановленный интерпретатором Python во время открытия файла, связанного с потоком вывода. Инструкция print скрывает большую часть этихподробностей, предоставляя простой инструмент для решения простых задачвывода.Перенаправление потока вывода вручнуюИтак, зачем я показал более сложный способ вывода? Как оказывается, объектsys.stdout обеспечивает возможность вывода, эквивалентную базовой методике, используемой в языке Python.
Вообще говоря, инструкция print и объектsys.stdout связаны между собой следующим образом. Инструкция:print(X, Y)# Или print X, Y в версии 2.6является эквивалентом более длинной:import syssys.stdout.write(str(X) + ‘ ‘ + str(Y) + ‘\n’)которая вручную выполняет преобразование объекта в строку с помощьюфункции str, добавляет символ конца строки с помощью оператора + и вызывает метод write потока вывода. А как бы вы выполнили ту же задачу? (Этимпримером мне хотелось бы подчеркнуть дружественную природу инструкцииprint...)Очевидно, что более длинная форма сама по себе менее удобна в использовании. Однако полезно знать, что она является точным эквивалентом инструкции print, потому что существует возможность переназначить sys.stdout начто-то, отличное от стандартного потока вывода.
Другими словами, эта эквивалентность обеспечивает возможность заставить инструкцию print выводитьтекст в другое место. Например:import syssys.stdout = open(‘log.txt’, ‘a’) # Перенаправить вывод в файл...Print(x, y, x)# Текст появится в файле log.txt369Операция printЗдесь мы вручную перенаправили объект sys.stdout в файл, открытый вручную в режиме добавления (так как мы добавляем новое содержимое). Послеэтого все инструкции print в программе будут выводить текст в конец файлаlog.txt, а не в стандартный поток вывода. Инструкции print благополучно продолжают вызывать метод write объекта sys.stdout независимо от того, куда онссылается.
Поскольку в каждом процессе существует всего один модуль sys,перенаправление sys.stdout таким способом будет воздействовать на все инструкции print в программе.Фактически, как будет говориться в ближайшей врезке, описывающей инструкцию print и объект stdout, существует возможность перенаправить sys.stdout в объект, который даже не является файлом, при условии, что он поддерживает ожидаемый интерфейс: метод write, принимающий строковый аргумент. Этот объект может быть классом, способным обрабатывать и перенаправлять выводимый текст произвольным образом.Этот прием с перенаправлением потока вывода в первую очередь может оказаться полезен в программах, изначально рассчитанных на использование инструкции print. Если известно, что весь вывод должен отправляться в файл, вывсегда сможете организовать вызов методов записи в файл.
При перенаправлении потока вывода в программах, основанных на использовании инструкцииprint, настройка объекта sys.stdout обеспечивает удобную альтернативу изменению поведения всех инструкций print или применению перенаправлениясредствами командной оболочки системы.Автоматическое перенаправление потоковПрием перенаправления вывода текста за счет назначения файла в объектеsys.stdout очень часто используется на практике. Однако в программном кодепредыдущего раздела имеется одна потенциальная проблема – отсутствуетпрямой способ восстановления первоначального потока вывода, если вдруг после вывода данных в файл потребуется вернуться обратно к выводу на экран.Но поскольку sys.stdout является обычным объектом, вы всегда можете в случае необходимости сохранить его и восстановить позднее:1C:\misc> c:\python30\python>>> import sys>>> temp = sys.stdout# Сохранить для последующего восстановления>>> sys.stdout = open(‘log.txt’, ‘a’) # Перенаправить вывод в файл>>> print(‘spam’)# Выведет в файл, а не на экран>>> print(1, 2, 3)>>> sys.stdout.close()# Вытолкнуть буферы на диск>>> sys.stdout = temp# Восстановить первоначальный поток>>> print(‘back here’)back here>>> print(open(‘log.txt’).read())spam1 2 31# Вывести на экран# Результаты более ранних обращений# к инструкции printВ обеих версиях, 2.6 и 3.0, можно также использовать атрибут __stdout__ модуля sys,который ссылается на первоначальное значение sys.stdout, имевшееся на моментзапуска программы.