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

inputoutput.md

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

1> **Источник:** https://python-all.ru/3.1/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/3.1/library/functions.html#print). (Третий способ – использовать метод `write()` файловых объектов; стандартный файл вывода можно указать как `sys.stdout`. Подробнее об этом см. в Справочнике по библиотеке.)1415Часто требуется более тонкое управление форматированием вывода, чем просто печать значений через пробел. Есть два способа форматирования: первый – обрабатывать строки самостоятельно, используя срезы и конкатенацию для создания любой желаемой разметки. Тип str имеет методы для полезных операций, таких как дополнение строк до заданной ширины столбца; о них будет сказано ниже. Второй способ – использовать метод [`str.format()`](https://python-all.ru/3.1/library/stdtypes.html#str.format).1617Модуль [`string`](https://python-all.ru/3.1/library/string.html#module-string) содержит класс [`Template`](https://python-all.ru/3.1/library/string.html#string.Template), который предлагает ещё один способ подстановки значений в строки.1819Остаётся, конечно, один вопрос: как преобразовать значения в строки? К счастью, в Python есть способы преобразовать любое значение в строку: передать его функции [`repr()`](https://python-all.ru/3.1/library/functions.html#repr) или [`str()`](https://python-all.ru/3.1/library/functions.html#str).2021Функция [`str()`](https://python-all.ru/3.1/library/functions.html#str) предназначена для возврата представлений значений, которые достаточно удобочитаемы, в то время как [`repr()`](https://python-all.ru/3.1/library/functions.html#repr) предназначена для генерации представлений, которые могут быть прочитаны интерпретатором (или вызовет [`SyntaxError`](https://python-all.ru/3.1/library/exceptions.html#SyntaxError), если нет эквивалентного синтаксиса). Для объектов, у которых нет специального представления для человеческого восприятия, [`str()`](https://python-all.ru/3.1/library/functions.html#str) вернёт то же значение, что и [`repr()`](https://python-all.ru/3.1/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(s)39The value of x is 32.5, and y is 40000...40>>> # repr() строки добавляет кавычки и обратную косую черту:41... hello = 'hello, world\n'42>>> hellos = repr(hello)43>>> print(hellos)44'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), end=' ')55...     # Обратите внимание на использование 'end' в предыдущей строке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/3.1/library/functions.html#print): она всегда добавляет пробелы между своими аргументами.)8586Этот пример демонстрирует метод [`str.rjust()`](https://python-all.ru/3.1/library/stdtypes.html#str.rjust) строковых объектов, который выравнивает строку по правому краю в поле заданной ширины, дополняя её слева пробелами. Есть аналогичные методы [`str.ljust()`](https://python-all.ru/3.1/library/stdtypes.html#str.ljust) и [`str.center()`](https://python-all.ru/3.1/library/stdtypes.html#str.center). Эти методы ничего не выводят, а просто возвращают новую строку. Если входная строка слишком длинная, они не обрезают её, а возвращают как есть; это нарушит разметку столбцов, но обычно это лучше, чем альтернатива, которая заключалась бы во лжи о значении. (Если обрезка действительно нужна, всегда можно добавить срез, например `x.ljust(n)[:n]`.)8788Существует ещё один метод, [`str.zfill()`](https://python-all.ru/3.1/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/3.1/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/3.1/library/stdtypes.html#str.format). Число в скобках может использоваться для указания позиции объекта, переданного методу [`str.format()`](https://python-all.ru/3.1/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/3.1/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`'!a'` (применить [`ascii()`](https://python-all.ru/3.1/library/functions.html#ascii)), `'!s'` (применить [`str()`](https://python-all.ru/3.1/library/functions.html#str)) и `'!r'` (применить [`repr()`](https://python-all.ru/3.1/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/3.1/library/functions.html#vars), которая возвращает словарь, содержащий все локальные переменные.179180Полный обзор форматирования строк с помощью [`str.format()`](https://python-all.ru/3.1/library/stdtypes.html#str.format) см. в [*Синтаксис строк формата*](https://python-all.ru/3.1/library/string.html#formatstrings).181182### 7.1.1. Старое форматирование строк183184Оператор `%` также можно использовать для форматирования строк. Он интерпретирует левый аргумент как строку формата в стиле `sprintf()`, которая применяется к правому аргументу, и возвращает строку, полученную в результате этой операции форматирования. Например:185186```python187>>> import math188>>> print('The value of PI is approximately %5.3f.' % math.pi)189The value of PI is approximately 3.142.190```191192Поскольку [`str.format()`](https://python-all.ru/3.1/library/stdtypes.html#str.format) появился недавно, многие программы на Python всё ещё используют `%` оператор. Однако, поскольку этот старый стиль форматирования планируется удалить из языка, рекомендуется использовать [`str.format()`](https://python-all.ru/3.1/library/stdtypes.html#str.format).193194Дополнительную информацию можно найти в разделе [*Старые операции форматирования строк*](https://python-all.ru/3.1/library/stdtypes.html#old-string-formatting).195196## 7.2. Чтение и запись файлов197198[`open()`](https://python-all.ru/3.1/library/functions.html#open) возвращает [*файловый объект*](https://python-all.ru/3.1/glossary.html#term-file-object) и чаще всего используется с двумя аргументами: `open(filename, mode)`.199200```python201>>> f = open('/tmp/workfile', 'w')202```203204Первый аргумент – строка с именем файла. Второй аргумент – ещё одна строка из нескольких символов, описывающая способ использования файла. *mode* может быть `'r'` для чтения, `'w'` для записи (существующий файл с таким именем будет стёрт), `'a'` открывает файл для добавления; любые записанные данные автоматически добавляются в конец. `'r+'` открывает файл для чтения и записи. Аргумент *mode* необязателен; если он опущен, используется `'r'`.205206Обычно файлы открываются в *текстовом режиме*, то есть вы читаете и записываете строки в файл и из файла, которые закодированы в определённой кодировке (по умолчанию UTF-8). Добавление `'b'` к режиму открывает файл в *двоичном режиме*: теперь данные читаются и записываются в виде объектов bytes. Этот режим следует использовать для всех файлов, которые не содержат текст.207208В текстовом режиме по умолчанию зависимые от платформы окончания строк (`\n` в Unix, `\r\n` в Windows) преобразуются в просто `\n` при чтении и `\n` обратно в зависимые от платформы окончания строк при записи. Это неявное изменение данных файла подходит для текстовых файлов, но испортит двоичные данные, такие как в файлах `JPEG` или `EXE`. При чтении и записи таких файлов следует обязательно использовать двоичный режим.209210### 7.2.1. Методы файловых объектов211212В остальных примерах этого раздела предполагается, что файловый объект с именем `f` уже создан.213214Чтобы прочитать содержимое файла, вызовите `f.read(size)`, которая читает некоторое количество данных и возвращает их в виде строки или объекта bytes. *size* – необязательный числовой аргумент. Если *size* опущен или отрицателен, будет прочитано и возвращено всё содержимое файла; это ваша проблема, если файл вдвое больше памяти вашей машины. В противном случае читается и возвращается не более *size* байтов. Если достигнут конец файла, `f.read()` вернёт пустую строку (`''`).215216```python217>>> f.read()218'This is the entire file.\n'219>>> f.read()220''221```222223`f.readline()` читает одну строку из файла; символ новой строки (``) остаётся в конце строки и опускается только для последней строки файла, если файл не заканчивается символом новой строки. Это делает возвращаемое значение однозначным: если `f.readline()` возвращает пустую строку, достигнут конец файла, а пустая строка представляется как `'\n'` – строка, содержащая только один символ новой строки.224225```python226>>> f.readline()227'This is the first line of the file.\n'228>>> f.readline()229'Second line of the file\n'230>>> f.readline()231''232```233234`f.readlines()` возвращает список, содержащий все строки данных из файла. Если указан необязательный параметр *sizehint*, он читает указанное количество байт из файла, а также ещё некоторое количество, достаточное для завершения строки, и возвращает строки из этого. Это часто используется для эффективного построчного чтения больших файлов без необходимости загружать весь файл в память. Возвращаются только полные строки.235236```python237>>> f.readlines()238['This is the first line of the file.\n', 'Second line of the file\n']239```240241Альтернативный подход к чтению строк – это организация цикла по файловому объекту. Он эффективен по памяти, быстр и ведёт к более простому коду:242243```python244>>> for line in f:245...     print(line, end='')246...247This is the first line of the file.248Second line of the file249```250251Альтернативный подход проще, но не обеспечивает такого же детального управления. Поскольку эти два подхода по-разному управляют буферизацией строк, их не следует смешивать.252253`f.write(string)` записывает содержимое *string* в файл, возвращая количество записанных символов.254255```python256>>> f.write('This is a test\n')25715258```259260Чтобы записать что-то, отличное от строки, его сначала нужно преобразовать в строку:261262```python263>>> value = ('the answer', 42)264>>> s = str(value)265>>> f.write(s)26618267```268269`f.tell()` возвращает целое число, представляющее текущую позицию файлового объекта в файле, измеряемую в байтах от начала файла. Чтобы изменить позицию файлового объекта, используйте `f.seek(offset, from_what)`. Позиция вычисляется как сумма *offset* и опорной точки; опорная точка выбирается аргументом *from\_what*. Значение *from\_what*, равное 0, задаёт начало файла, 1 – текущую позицию, а 2 – конец файла в качестве опорной точки. Значение *from\_what* может быть опущено; по умолчанию оно равно 0, что соответствует началу файла.270271```python272>>> f = open('/tmp/workfile', 'rb+')273>>> f.write(b'0123456789abcdef')27416275>>> f.seek(5)     # Перейти к 6-му байту в файле2765277>>> f.read(1)278b'5'279>>> f.seek(-3, 2) # Перейти к 3-му байту от конца28013281>>> f.read(1)282b'd'283```284285В текстовых файлах (открытых без `b` в строке режима) разрешён только поиск относительно начала файла (исключение составляет поиск до самого конца файла с помощью `seek(0, 2)`).286287Когда работа с файлом завершена, вызовите `f.close()`, чтобы закрыть его и освободить системные ресурсы, занятые открытым файлом. После вызова `f.close()` попытки использовать файловый объект будут автоматически завершаться неудачей.288289```python290>>> f.close()291>>> f.read()292Traceback (most recent call last):293  File "<stdin>", line 1, in ?294ValueError: I/O operation on closed file295```296297Хорошей практикой является использование ключевого слова [`with`](https://python-all.ru/3.1/reference/compound_stmts.html#with) при работе с файловыми объектами. Его преимущество в том, что файл корректно закрывается после завершения блока, даже если в процессе возникло исключение. Кроме того, это гораздо короче, чем писать эквивалентные блоки [`try`](https://python-all.ru/3.1/reference/compound_stmts.html#try)-[`finally`](https://python-all.ru/3.1/reference/compound_stmts.html#finally):298299```python300>>> with open('/tmp/workfile', 'r') as f:301...     read_data = f.read()302>>> f.closed303True304```305306Файловые объекты имеют некоторые дополнительные методы, такие как `isatty()` и `truncate()`, которые используются реже; полное руководство по файловым объектам см. в Справочнике по библиотеке.307308### 7.2.2. Модуль [`pickle`](https://python-all.ru/3.1/library/pickle.html#module-pickle)309310Строки легко записываются и читаются из файла. С числами немного сложнее, поскольку метод `read()` возвращает только строки, которые нужно передать такой функции, как [`int()`](https://python-all.ru/3.1/library/functions.html#int), которая принимает строку вида `'123'` и возвращает её числовое значение 123. Однако, когда нужно сохранить более сложные типы данных, такие как списки, словари или экземпляры классов, всё становится гораздо сложнее.311312Вместо того чтобы постоянно писать и отлаживать код для сохранения сложных типов данных, Python предлагает стандартный модуль [`pickle`](https://python-all.ru/3.1/library/pickle.html#module-pickle). Это удивительный модуль, который может взять почти любой объект Python (даже некоторые формы кода Python!) и преобразовать его в строковое представление; этот процесс называется *упаковкой в pickle (pickling)*. Восстановление объекта из строкового представления называется *распаковкой из pickle (unpickling)*. Между упаковкой и распаковкой строковое представление объекта может быть сохранено в файл или данные, или передано по сетевому соединению на удалённую машину.313314Если есть объект `x` и файловый объект `f`, открытый для записи, самый простой способ упаковать объект с помощью pickle занимает всего одну строку кода:315316```python317pickle.dump(x, f)318```319320Чтобы снова распаковать объект, если `f` – это файловый объект, открытый для чтения:321322```python323x = pickle.load(f)324```325326(Существуют и другие варианты, используемые при упаковке множества объектов или когда не хочется записывать упакованные данные в файл; обратитесь к полной dокументации модуля [`pickle`](https://python-all.ru/3.1/library/pickle.html#module-pickle) в Python Library Reference.)327328[`pickle`](https://python-all.ru/3.1/library/pickle.html#module-pickle) – это стандартный способ создания объектов Python, которые могут быть сохранены и повторно использованы другими программами или при будущих запусках той же программы; технический термин для этого – *постоянный объект (persistent object)*. Так как [`pickle`](https://python-all.ru/3.1/library/pickle.html#module-pickle) так широко используется, многие авторы, пишущие расширения Python, заботятся о том, чтобы новые типы данных, такие как матрицы, могли быть правильно упакованы и распакованы с помощью pickle.329