Документация Python неофициальный перевод

inputoutput.md

329 строк · 26.2 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.7/tutorial/inputoutput.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 7. Ввод и вывод89Есть несколько способов отображения вывода программы: данные можно выводить в удобочитаемой форме или записывать в файл для последующего использования. В этой главе рассматриваются некоторые из возможностей.1011## 7.1. Более изощрённое форматирование вывода1213До сих пор мы встречали два способа вывода значений: *инструкции-выражения* и инструкция [`print`](https://python-all.ru/2.7/reference/simple_stmts.html#print). (Третий способ – использовать метод `write()` файловых объектов; стандартный выходной файл можно обозначить как `sys.stdout`. Дополнительную информацию можно найти в Справочнике по библиотеке.)1415Часто требуется более точное управление форматированием вывода, чем просто печать значений, разделённых пробелами. Существует два способа форматирования вывода: первый – выполнить всю обработку строк самостоятельно; используя операции извлечения подстрок и конкатенации, можно создать любой макет. Строковые типы имеют несколько методов, выполняющих полезные операции по дополнению строк до заданной ширины столбца; они будут рассмотрены далее. Второй способ – использовать метод [`str.format()`](https://python-all.ru/2.7/library/stdtypes.html#str.format).1617Модуль [`string`](https://python-all.ru/2.7/library/string.html#module-string) содержит класс [`Template`](https://python-all.ru/2.7/library/string.html#string.Template), который предлагает ещё один способ подстановки значений в строки.1819Остаётся, конечно, один вопрос: как преобразовать значения в строки? К счастью, в Python есть способы преобразовать любое значение в строку: передать его функциям [`repr()`](https://python-all.ru/2.7/library/functions.html#repr) или [`str()`](https://python-all.ru/2.7/library/functions.html#str).2021Функция [`str()`](https://python-all.ru/2.7/library/functions.html#str) предназначена для возврата представлений значений, которые достаточно читаемы для человека, в то время как [`repr()`](https://python-all.ru/2.7/library/functions.html#repr) предназначена для генерации представлений, которые могут быть прочитаны интерпретатором (или вызовет [`SyntaxError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.SyntaxError), если нет эквивалентного синтаксиса). Для объектов, не имеющих специального представления для человека, [`str()`](https://python-all.ru/2.7/library/functions.html#str) вернёт то же значение, что и [`repr()`](https://python-all.ru/2.7/library/functions.html#repr). Многие значения, такие как числа или структуры вроде списков и словарей, имеют одинаковое представление при использовании любой функции. Строки и числа с плавающей точкой, в частности, имеют два различных представления.2223Несколько примеров:2425```python26>>> s = 'Hello, world.'27>>> str(s)28'Hello, world.'29>>> repr(s)30"'Hello, world.'"31>>> str(1.0/7.0)32'0.142857142857'33>>> repr(1.0/7.0)34'0.14285714285714285'35>>> x = 10 * 3.2536>>> y = 200 * 20037>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'38>>> print s39The value of x is 32.5, and y is 40000...40>>> # repr() строки добавляет кавычки и обратную косую черту:41... hello = 'hello, world\n'42>>> hellos = repr(hello)43>>> print hellos44'hello, world\n'45>>> # Аргументом repr() может быть любой объект Python:46... repr((x, y, ('spam', 'eggs')))47"(32.5, 40000, ('spam', 'eggs'))"48```4950Вот два способа вывести таблицу квадратов и кубов:5152```python53>>> for x in range(1, 11):54...     print repr(x).rjust(2), repr(x*x).rjust(3),55...     # Примечание: завершающая запятая на предыдущей строке56...     print repr(x*x*x).rjust(4)57...58 1   1    159 2   4    860 3   9   2761 4  16   6462 5  25  12563 6  36  21664 7  49  34365 8  64  51266 9  81  7296710 100 10006869>>> for x in range(1,11):70...     print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)71...72 1   1    173 2   4    874 3   9   2775 4  16   6476 5  25  12577 6  36  21678 7  49  34379 8  64  51280 9  81  7298110 100 100082```8384(Обратите внимание, что в первом примере один пробел между столбцами добавляется из-за того, как работает [`print`](https://python-all.ru/2.7/reference/simple_stmts.html#print): по умолчанию он добавляет пробелы между своими аргументами.)8586Этот пример демонстрирует метод [`str.rjust()`](https://python-all.ru/2.7/library/stdtypes.html#str.rjust) строковых объектов, который выравнивает строку по правому краю в поле заданной ширины, дополняя её пробелами слева. Существуют аналогичные методы [`str.ljust()`](https://python-all.ru/2.7/library/stdtypes.html#str.ljust) и [`str.center()`](https://python-all.ru/2.7/library/stdtypes.html#str.center). Эти методы ничего не выводят, они просто возвращают новую строку. Если входная строка слишком длинная, они не обрезают её, а возвращают без изменений; это может испортить выравнивание столбцов, но обычно это лучше, чем альтернатива – искажать значение. (Если обрезка действительно нужна, всегда можно добавить срез, как в `x.ljust(n)[:n]`.)8788Существует ещё один метод, [`str.zfill()`](https://python-all.ru/2.7/library/stdtypes.html#str.zfill), который дополняет числовую строку слева нулями. Он учитывает знаки плюс и минус:8990```python91>>> '12'.zfill(5)92'00012'93>>> '-3.14'.zfill(7)94'-003.14'95>>> '3.14159265359'.zfill(5)96'3.14159265359'97```9899Базовое использование метода [`str.format()`](https://python-all.ru/2.7/library/stdtypes.html#str.format) выглядит так:100101```python102>>> print 'We are the {} who say "{}!"'.format('knights', 'Ni')103We are the knights who say "Ni!"104```105106Фигурные скобки и символы внутри них (называемые полями формата) заменяются объектами, переданными в метод [`str.format()`](https://python-all.ru/2.7/library/stdtypes.html#str.format). Число в скобках указывает позицию объекта, переданного в метод [`str.format()`](https://python-all.ru/2.7/library/stdtypes.html#str.format).107108```python109>>> print '{0} and {1}'.format('spam', 'eggs')110spam and eggs111>>> print '{1} and {0}'.format('spam', 'eggs')112eggs and spam113```114115Если в методе [`str.format()`](https://python-all.ru/2.7/library/stdtypes.html#str.format) используются именованные аргументы, на их значения ссылаются по имени аргумента.116117```python118>>> print 'This {food} is {adjective}.'.format(119...       food='spam', adjective='absolutely horrible')120This spam is absolutely horrible.121```122123Позиционные и именованные аргументы можно произвольно комбинировать:124125```python126>>> print 'The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',127...                                                    other='Georg')128The story of Bill, Manfred, and Georg.129```130131`'!s'` (применить [`str()`](https://python-all.ru/2.7/library/functions.html#str)) и `'!r'` (применить [`repr()`](https://python-all.ru/2.7/library/functions.html#repr)) можно использовать для преобразования значения перед форматированием.132133```python134>>> import math135>>> print 'The value of PI is approximately {}.'.format(math.pi)136The value of PI is approximately 3.14159265359.137>>> print 'The value of PI is approximately {!r}.'.format(math.pi)138The value of PI is approximately 3.141592653589793.139```140141После имени поля могут следовать необязательные `':'` и спецификатор формата. Это позволяет более гибко управлять форматированием значения. В следующем примере значение Pi округляется до трёх знаков после запятой.142143```python144>>> import math145>>> print 'The value of PI is approximately {0:.3f}.'.format(math.pi)146The value of PI is approximately 3.142.147```148149Передача целого числа после `':'` задаёт минимальную ширину поля в символах. Это удобно для красивых таблиц.150151```python152>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}153>>> for name, phone in table.items():154...     print '{0:10} ==> {1:10d}'.format(name, phone)155...156Jack       ==>       4098157Dcab       ==>       7678158Sjoerd     ==>       4127159```160161Если у вас очень длинная строка форматирования, которую не хочется разбивать, было бы удобно ссылаться на переменные по имени, а не по позиции. Это можно сделать, просто передав словарь и используя квадратные скобки `'[]'` для доступа к ключам.162163```python164>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}165>>> print ('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '166...        'Dcab: {0[Dcab]:d}'.format(table))167Jack: 4098; Sjoerd: 4127; Dcab: 8637678168```169170Это также можно сделать, передав таблицу как именованные аргументы с помощью нотации ‘\*\*’ .171172```python173>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}174>>> print 'Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)175Jack: 4098; Sjoerd: 4127; Dcab: 8637678176```177178Это особенно полезно в сочетании со встроенной функцией [`vars()`](https://python-all.ru/2.7/library/functions.html#vars), которая возвращает словарь, содержащий все локальные переменные.179180Полный обзор форматирования строк с помощью [`str.format()`](https://python-all.ru/2.7/library/stdtypes.html#str.format) см. в [Синтаксисе строк форматирования](https://python-all.ru/2.7/library/string.html#formatstrings).181182### 7.1.1. Старое форматирование строк183184Оператор `%` также можно использовать для форматирования строк. Он интерпретирует левый аргумент как строку формата в стиле `sprintf()`, которая применяется к правому аргументу, и возвращает строку, полученную в результате форматирования. Например:185186```python187>>> import math188>>> print 'The value of PI is approximately %5.3f.' % math.pi189The value of PI is approximately 3.142.190```191192Дополнительную информацию можно найти в разделе [Операции форматирования строк](https://python-all.ru/2.7/library/stdtypes.html#string-formatting).193194## 7.2. Чтение и запись файлов195196[`open()`](https://python-all.ru/2.7/library/functions.html#open) возвращает файловый объект и чаще всего используется с двумя аргументами: `open(filename, mode)`.197198```python199>>> f = open('workfile', 'w')200>>> print f201<open file 'workfile', mode 'w' at 80a0960>202```203204Первый аргумент – строка, содержащая имя файла. Второй аргумент – ещё одна строка, содержащая несколько символов, описывающих способ использования файла. *mode* может быть `'r'` для чтения, `'w'` только для записи (существующий файл с таким же именем будет стёрт), а `'a'` открывает файл для дополнения; любые записанные данные автоматически добавляются в конец. `'r+'` открывает файл и для чтения, и для записи. Аргумент *mode* необязателен; если он опущен, предполагается `'r'`.205206В Windows добавление `'b'` к режиму открывает файл в двоичном режиме, поэтому существуют также режимы `'rb'`, `'wb'` и `'r+b'`. Python в Windows различает текстовые и двоичные файлы; символы конца строки в текстовых файлах автоматически слегка изменяются при чтении или записи данных. Это скрытое изменение данных файла нормально для текстовых файлов ASCII, но повредит двоичные данные, например, в файлах `JPEG` или `EXE`. Требуется особая осторожность при использовании двоичного режима для чтения и записи таких файлов. В Unix добавление `'b'` к режиму не вредит, поэтому его можно использовать независимо от платформы для всех двоичных файлов.207208### 7.2.1. Методы файловых объектов209210Остальные примеры в этом разделе предполагают, что файловый объект с именем `f` уже создан.211212Чтобы прочитать содержимое файла, вызовите `f.read(size)`, которая считывает некоторое количество данных и возвращает их в виде строки. *size* – необязательный числовой аргумент. Если *size* опущен или отрицателен, будет прочитано и возвращено всё содержимое файла; это ваша проблема, если файл вдвое больше памяти вашего компьютера. В противном случае будет прочитано и возвращено не более *size* байт. Если достигнут конец файла, `f.read()` вернёт пустую строку (`""`).213214```python215>>> f.read()216'This is the entire file.\n'217>>> f.read()218''219```220221`f.readline()` читает одну строку из файла; символ новой строки (`\n`) остаётся в конце строки и опускается только в последней строке файла, если файл не заканчивается переводом строки. Это делает возвращаемое значение однозначным: если `f.readline()` возвращает пустую строку, конец файла достигнут, тогда как пустая строка представляется как `'\n'`, строка, содержащая только один символ новой строки.222223```python224>>> f.readline()225'This is the first line of the file.\n'226>>> f.readline()227'Second line of the file\n'228>>> f.readline()229''230```231232Для чтения строк из файла можно выполнять итерацию по файловому объекту. Это эффективно по памяти, быстро и приводит к простому коду:233234```python235>>> for line in f:236        print line,237238This is the first line of the file.239Second line of the file240```241242Если нужно прочитать все строки файла в виде списка, можно также использовать `list(f)` или `f.readlines()`.243244`f.write(string)` записывает содержимое *string* в файл и возвращает `None`.245246```python247>>> f.write('This is a test\n')248```249250Чтобы записать что-то, отличное от строки, его сначала нужно преобразовать в строку:251252```python253>>> value = ('the answer', 42)254>>> s = str(value)255>>> f.write(s)256```257258`f.tell()` возвращает целое число, указывающее текущую позицию файлового объекта в файле, измеряемую в байтах от начала файла. Чтобы изменить позицию файлового объекта, используйте `f.seek(offset, from_what)`. Позиция вычисляется прибавлением *offset* к опорной точке; опорная точка выбирается аргументом *from\_what*. Значение *from\_what*, равное 0, отсчитывает от начала файла, 1 – от текущей позиции, а 2 – от конца файла. *from\_what* можно опустить; по умолчанию используется 0, то есть начало файла.259260```python261>>> f = open('workfile', 'r+')262>>> f.write('0123456789abcdef')263>>> f.seek(5)      # Перейти к 6-му байту в файле264>>> f.read(1)265'5'266>>> f.seek(-3, 2)  # Перейти к 3-му байту от конца267>>> f.read(1)268'd'269```270271Когда работа с файлом завершена, вызовите `f.close()`, чтобы закрыть его и освободить все системные ресурсы, занятые открытым файлом. После вызова `f.close()` попытки использовать файловый объект будут автоматически завершаться ошибкой.272273```python274>>> f.close()275>>> f.read()276Traceback (most recent call last):277  File "<stdin>", line 1, in <module>278ValueError: I/O operation on closed file279```280281Рекомендуется использовать ключевое слово [`with`](https://python-all.ru/2.7/reference/compound_stmts.html#with) при работе с файловыми объектами. Это гарантирует, что файл будет корректно закрыт после завершения своего блока, даже если возникнет исключение. Кроме того, это гораздо короче, чем писать эквивалентные блоки [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try)-[`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally):282283```python284>>> with open('workfile', 'r') as f:285...     read_data = f.read()286>>> f.closed287True288```289290Файловые объекты имеют некоторые дополнительные методы, такие как [`isatty()`](https://python-all.ru/2.7/library/stdtypes.html#file.isatty) и [`truncate()`](https://python-all.ru/2.7/library/stdtypes.html#file.truncate), которые используются реже; обратитесь к Справочнику библиотеки для получения полного руководства по файловым объектам.291292### 7.2.2. Сохранение структурированных данных с помощью [`json`](https://python-all.ru/2.7/library/json.html#module-json)293294Строки можно легко записать в файл и прочитать из файла. С числами немного сложнее, поскольку метод `read()` возвращает только строки, которые затем нужно передать такой функции, как [`int()`](https://python-all.ru/2.7/library/functions.html#int), принимающей строку вида `'123'` и возвращающей её числовое значение 123. Если требуется сохранять более сложные типы данных, например вложенные списки и словари, ручной разбор и сериализация становятся сложными.295296Чтобы избавить пользователей от постоянного написания и отладки кода для сохранения сложных типов данных в файлы, Python позволяет использовать популярный формат обмена данными, называемый [JSON (JavaScript Object Notation)](https://python-all.ru/2.7/tutorial/inputoutput.html). Стандартный модуль [`json`](https://python-all.ru/2.7/library/json.html#module-json) может обрабатывать иерархии данных Python и преобразовывать их в строковые представления; этот процесс называется *сериализацией*. Восстановление данных из строкового представления называется *десериализацией*. Между сериализацией и десериализацией строка, представляющая объект, может быть сохранена в файл или данные, либо передана по сетевому соединению на удалённую машину.297298> **Примечание**299>300> Формат JSON широко используется в современных приложениях для обмена данными. Многие программисты уже знакомы с ним, что делает его хорошим выбором для обеспечения совместимости.301302Если у вас есть объект `x`, вы можете увидеть его строковое представление в JSON одной строкой кода:303304```python305>>> import json306>>> json.dumps([1, 'simple', 'list'])307'[1, "simple", "list"]'308```309310Другой вариант функции [`dumps()`](https://python-all.ru/2.7/library/json.html#json.dumps), называемый [`dump()`](https://python-all.ru/2.7/library/json.html#json.dump), просто сериализует объект в файл. Так, если `f` – это [файловый объект](https://python-all.ru/2.7/glossary.html#term-file-object), открытый для записи, можно сделать следующее:311312```python313json.dump(x, f)314```315316Чтобы снова декодировать объект, если `f` – это [файловый объект](https://python-all.ru/2.7/glossary.html#term-file-object), открытый для чтения:317318```python319x = json.load(f)320```321322Этот простой метод сериализации может обрабатывать списки и словари, но для сериализации произвольных экземпляров классов в JSON требуется немного дополнительных усилий. В справочнике по модулю [`json`](https://python-all.ru/2.7/library/json.html#module-json) есть объяснение этого.323324> **См. также**325>326> [`pickle`](https://python-all.ru/2.7/library/pickle.html#module-pickle) – модуль pickle327>328> В отличие от [JSON](https://python-all.ru/2.7/tutorial/inputoutput.html#tut-json), *pickle* – это протокол, позволяющий сериализовывать произвольно сложные объекты Python. Поэтому он специфичен для Python и не может использоваться для взаимодействия с приложениями, написанными на других языках. Кроме того, по умолчанию он небезопасен: десериализация данных pickle из ненадёжного источника может выполнить произвольный код, если данные были подготовлены опытным злоумышленником.329