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

inputoutput.md

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

1> **Источник:** https://python-all.ru/3.3/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.3/library/functions.html#print). (Третий способ – использовать метод `write()` файловых объектов; стандартный файл вывода можно указать как `sys.stdout`. Подробнее об этом см. в Справочнике по библиотеке.)1415Часто требуется более тонкое управление форматированием вывода, чем просто печать значений через пробел. Есть два способа форматирования: первый – обрабатывать строки самостоятельно, используя срезы и конкатенацию для создания любой желаемой разметки. Тип str имеет методы для полезных операций, таких как дополнение строк до заданной ширины столбца; о них будет сказано ниже. Второй способ – использовать метод [`str.format()`](https://python-all.ru/3.3/library/stdtypes.html#str.format).1617Модуль [`string`](https://python-all.ru/3.3/library/string.html#module-string) содержит класс [`Template`](https://python-all.ru/3.3/library/string.html#string.Template), который предлагает ещё один способ подстановки значений в строки.1819Остаётся, конечно, один вопрос: как преобразовать значения в строки? К счастью, в Python есть способы преобразовать любое значение в строку: передать его функции [`repr()`](https://python-all.ru/3.3/library/functions.html#repr) или [`str()`](https://python-all.ru/3.3/library/stdtypes.html#str).2021Функция [`str()`](https://python-all.ru/3.3/library/stdtypes.html#str) предназначена для возврата представлений значений, удобных для человека, а [`repr()`](https://python-all.ru/3.3/library/functions.html#repr) – для генерации представлений, читаемых интерпретатором (или вызовет [`SyntaxError`](https://python-all.ru/3.3/library/exceptions.html#SyntaxError), если эквивалентного синтаксиса нет). Для объектов, у которых нет специального представления для человека, [`str()`](https://python-all.ru/3.3/library/stdtypes.html#str) вернёт то же значение, что и [`repr()`](https://python-all.ru/3.3/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/7)32'0.14285714285714285'33>>> x = 10 * 3.2534>>> y = 200 * 20035>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'36>>> print(s)37The value of x is 32.5, and y is 40000...38>>> # repr() строки добавляет кавычки и обратную косую черту:39... hello = 'hello, world\n'40>>> hellos = repr(hello)41>>> print(hellos)42'hello, world\n'43>>> # Аргументом repr() может быть любой объект Python:44... repr((x, y, ('spam', 'eggs')))45"(32.5, 40000, ('spam', 'eggs'))"46```4748Вот два способа вывести таблицу квадратов и кубов:4950```python51>>> for x in range(1, 11):52...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')53...     # Обратите внимание на использование 'end' в предыдущей строке54...     print(repr(x*x*x).rjust(4))55...56 1   1    157 2   4    858 3   9   2759 4  16   6460 5  25  12561 6  36  21662 7  49  34363 8  64  51264 9  81  7296510 100 10006667>>> for x in range(1, 11):68...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))69...70 1   1    171 2   4    872 3   9   2773 4  16   6474 5  25  12575 6  36  21676 7  49  34377 8  64  51278 9  81  7297910 100 100080```8182(Обратите внимание, что в первом примере один пробел между столбцами добавляется из-за того, как работает [`print()`](https://python-all.ru/3.3/library/functions.html#print): она всегда добавляет пробелы между своими аргументами.)8384Этот пример демонстрирует метод [`str.rjust()`](https://python-all.ru/3.3/library/stdtypes.html#str.rjust) строковых объектов, который выравнивает строку по правому краю в поле заданной ширины, дополняя её слева пробелами. Есть аналогичные методы [`str.ljust()`](https://python-all.ru/3.3/library/stdtypes.html#str.ljust) и [`str.center()`](https://python-all.ru/3.3/library/stdtypes.html#str.center). Эти методы ничего не выводят, а просто возвращают новую строку. Если входная строка слишком длинная, они не обрезают её, а возвращают как есть; это нарушит разметку столбцов, но обычно это лучше, чем альтернатива, которая заключалась бы во лжи о значении. (Если обрезка действительно нужна, всегда можно добавить срез, например `x.ljust(n)[:n]`.)8586Существует ещё один метод, [`str.zfill()`](https://python-all.ru/3.3/library/stdtypes.html#str.zfill), который дополняет числовую строку слева нулями. Он учитывает знаки плюс и минус:8788```python89>>> '12'.zfill(5)90'00012'91>>> '-3.14'.zfill(7)92'-003.14'93>>> '3.14159265359'.zfill(5)94'3.14159265359'95```9697Базовое использование метода [`str.format()`](https://python-all.ru/3.3/library/stdtypes.html#str.format) выглядит так:9899```python100>>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))101We are the knights who say "Ni!"102```103104Скобки и символы внутри них (называемые полями формата) заменяются объектами, переданными методу [`str.format()`](https://python-all.ru/3.3/library/stdtypes.html#str.format). Число в скобках может использоваться для указания позиции объекта, переданного методу [`str.format()`](https://python-all.ru/3.3/library/stdtypes.html#str.format).105106```python107>>> print('{0} and {1}'.format('spam', 'eggs'))108spam and eggs109>>> print('{1} and {0}'.format('spam', 'eggs'))110eggs and spam111```112113Если в методе [`str.format()`](https://python-all.ru/3.3/library/stdtypes.html#str.format) используются именованные аргументы, их значения указываются по имени аргумента.114115```python116>>> print('This {food} is {adjective}.'.format(117...       food='spam', adjective='absolutely horrible'))118This spam is absolutely horrible.119```120121Позиционные и именованные аргументы можно произвольно комбинировать:122123```python124>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',125                                                       other='Georg'))126The story of Bill, Manfred, and Georg.127```128129`'!a'` (применить [`ascii()`](https://python-all.ru/3.3/library/functions.html#ascii)), `'!s'` (применить [`str()`](https://python-all.ru/3.3/library/stdtypes.html#str)) и `'!r'` (применить [`repr()`](https://python-all.ru/3.3/library/functions.html#repr)) можно использовать для преобразования значения перед форматированием:130131```python132>>> import math133>>> print('The value of PI is approximately {}.'.format(math.pi))134The value of PI is approximately 3.14159265359.135>>> print('The value of PI is approximately {!r}.'.format(math.pi))136The value of PI is approximately 3.141592653589793.137```138139После имени поля могут следовать необязательные `':'` и спецификатор формата. Это позволяет более гибко управлять форматированием значения. В следующем примере значение Pi округляется до трёх знаков после запятой.140141```python142>>> import math143>>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))144The value of PI is approximately 3.142.145```146147Передача целого числа после `':'` задаёт минимальную ширину поля в символах. Это удобно для красивых таблиц.148149```python150>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}151>>> for name, phone in table.items():152...     print('{0:10} ==> {1:10d}'.format(name, phone))153...154Jack       ==>       4098155Dcab       ==>       7678156Sjoerd     ==>       4127157```158159Если у вас очень длинная строка форматирования, которую не хочется разбивать, было бы удобно ссылаться на переменные по имени, а не по позиции. Это можно сделать, просто передав словарь и используя квадратные скобки `'[]'` для доступа к ключам.160161```python162>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}163>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '164...       'Dcab: {0[Dcab]:d}'.format(table))165Jack: 4098; Sjoerd: 4127; Dcab: 8637678166```167168Это также можно сделать, передав таблицу как именованные аргументы с помощью нотации ‘\*\*’ .169170```python171>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}172>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))173Jack: 4098; Sjoerd: 4127; Dcab: 8637678174```175176Это особенно полезно в сочетании со встроенной функцией [`vars()`](https://python-all.ru/3.3/library/functions.html#vars), которая возвращает словарь, содержащий все локальные переменные.177178Полный обзор форматирования строк с помощью [`str.format()`](https://python-all.ru/3.3/library/stdtypes.html#str.format) см. в [*Синтаксис строк формата*](https://python-all.ru/3.3/library/string.html#formatstrings).179180### 7.1.1. Старое форматирование строк181182Оператор `%` также можно использовать для форматирования строк. Он интерпретирует левый аргумент как строку формата в стиле `sprintf()`, которая применяется к правому аргументу, и возвращает строку, полученную в результате этой операции форматирования. Например:183184```python185>>> import math186>>> print('The value of PI is approximately %5.3f.' % math.pi)187The value of PI is approximately 3.142.188```189190Дополнительную информацию можно найти в разделе [*Форматирование строк в стиле printf*](https://python-all.ru/3.3/library/stdtypes.html#old-string-formatting).191192## 7.2. Чтение и запись файлов193194[`open()`](https://python-all.ru/3.3/library/functions.html#open) возвращает [*файловый объект*](https://python-all.ru/3.3/glossary.html#term-file-object) и чаще всего используется с двумя аргументами: `open(filename, mode)`.195196```python197>>> f = open('workfile', 'w')198```199200Первый аргумент – строка с именем файла. Второй аргумент – ещё одна строка из нескольких символов, описывающая способ использования файла. *mode* может быть `'r'` для чтения, `'w'` для записи (существующий файл с таким именем будет стёрт), `'a'` открывает файл для добавления; любые записанные данные автоматически добавляются в конец. `'r+'` открывает файл для чтения и записи. Аргумент *mode* необязателен; если он опущен, используется `'r'`.201202Обычно файлы открываются в *текстовом режиме*, то есть вы читаете и записываете строки в файл и из файла, которые закодированы в определённой кодировке (по умолчанию UTF-8). Добавление `'b'` к режиму открывает файл в *двоичном режиме*: теперь данные читаются и записываются в виде объектов bytes. Этот режим следует использовать для всех файлов, которые не содержат текст.203204В текстовом режиме при чтении по умолчанию концы строк, специфичные для платформы (`` в Unix, `` в Windows), преобразуются в просто ``. При записи в текстовом режиме по умолчанию вхождения `` преобразуются обратно в концы строк, специфичные для платформы. Эта незаметная модификация данных файла нормальна для текстовых файлов, но испортит двоичные данные, такие как в файлах `JPEG` или `EXE`. Будьте очень внимательны и используйте двоичный режим при чтении и записи таких файлов.205206### 7.2.1. Методы файловых объектов207208В остальных примерах этого раздела предполагается, что файловый объект с именем `f` уже создан.209210Чтобы прочитать содержимое файла, вызовите `f.read(size)`, которая читает некоторое количество данных и возвращает их в виде строки или объекта bytes. *size* – необязательный числовой аргумент. Если *size* опущен или отрицателен, будет прочитано и возвращено всё содержимое файла; это ваша проблема, если файл вдвое больше памяти вашей машины. В противном случае читается и возвращается не более *size* байтов. Если достигнут конец файла, `f.read()` вернёт пустую строку (`''`).211212```python213>>> f.read()214'This is the entire file.\n'215>>> f.read()216''217```218219`f.readline()` читает одну строку из файла; символ новой строки (``) остаётся в конце строки и опускается только для последней строки файла, если файл не заканчивается символом новой строки. Это делает возвращаемое значение однозначным: если `f.readline()` возвращает пустую строку, достигнут конец файла, а пустая строка представляется как `'\n'` – строка, содержащая только один символ новой строки.220221```python222>>> f.readline()223'This is the first line of the file.\n'224>>> f.readline()225'Second line of the file\n'226>>> f.readline()227''228```229230Для чтения строк из файла можно выполнять итерацию по файловому объекту. Это эффективно по памяти, быстро и приводит к простому коду:231232```python233>>> for line in f:234...     print(line, end='')235...236This is the first line of the file.237Second line of the file238```239240Если нужно прочитать все строки файла в список, можно также использовать `list(f)` или `f.readlines()`.241242`f.write(string)` записывает содержимое *string* в файл, возвращая количество записанных символов.243244```python245>>> f.write('This is a test\n')24615247```248249Чтобы записать что-то, отличное от строки, его сначала нужно преобразовать в строку:250251```python252>>> value = ('the answer', 42)253>>> s = str(value)254>>> f.write(s)25518256```257258`f.tell()` возвращает целое число, указывающее текущую позицию файлового объекта в файле, представленную как количество байт от начала файла в *двоичном режиме* и непрозрачное число в *текстовом режиме*.259260Чтобы изменить позицию файлового объекта, используйте `f.seek(offset, from_what)`. Позиция вычисляется как сумма *offset* и точки отсчёта; точка отсчёта выбирается аргументом *from\_what*. Значение *from\_what*, равное 0, задаёт отсчёт от начала файла, 1 – от текущей позиции, 2 – от конца файла. *from\_what* можно опустить, по умолчанию 0 – начало файла.261262```python263>>> f = open('workfile', 'rb+')264>>> f.write(b'0123456789abcdef')26516266>>> f.seek(5)     # Перейти к 6-му байту в файле2675268>>> f.read(1)269b'5'270>>> f.seek(-3, 2) # Перейти к 3-му байту от конца27113272>>> f.read(1)273b'd'274```275276В текстовых файлах (открытых без `b` в строке режима) разрешены только перемещения относительно начала файла (исключение – перемещение в самый конец файла с помощью `seek(0, 2)`), и единственные допустимые значения *offset* – это значения, возвращённые `f.tell()`, или ноль. Любое другое значение *offset* приводит к неопределённому поведению.277278Когда работа с файлом завершена, вызовите `f.close()`, чтобы закрыть его и освободить системные ресурсы, занятые открытым файлом. После вызова `f.close()` попытки использовать файловый объект будут автоматически завершаться неудачей.279280```python281>>> f.close()282>>> f.read()283Traceback (most recent call last):284  File "<stdin>", line 1, in ?285ValueError: I/O operation on closed file286```287288Хорошей практикой является использование ключевого слова [`with`](https://python-all.ru/3.3/reference/compound_stmts.html#with) при работе с файловыми объектами. Его преимущество в том, что файл корректно закрывается после завершения блока, даже если в процессе возникло исключение. Кроме того, это гораздо короче, чем писать эквивалентные блоки [`try`](https://python-all.ru/3.3/reference/compound_stmts.html#try)-[`finally`](https://python-all.ru/3.3/reference/compound_stmts.html#finally):289290```python291>>> with open('workfile', 'r') as f:292...     read_data = f.read()293>>> f.closed294True295```296297Файловые объекты имеют некоторые дополнительные методы, такие как `isatty()` и `truncate()`, которые используются реже; полное руководство по файловым объектам см. в Справочнике по библиотеке.298299### 7.2.2. Сохранение структурированных данных с помощью [`json`](https://python-all.ru/3.3/library/json.html#module-json)300301Строки легко записываются в файл и читаются из файла. С числами немного больше усилий, так как метод `read()` возвращает только строки, которые нужно передавать функции вроде [`int()`](https://python-all.ru/3.3/library/functions.html#int), которая принимает строку типа `'123'` и возвращает её числовое значение 123. Когда требуется сохранить более сложные типы данных, такие как вложенные списки и словари, разбор и сериализация вручную становятся сложными.302303Вместо того чтобы пользователям приходилось постоянно писать и отлаживать код для сохранения сложных типов данных в файлы, Python позволяет использовать популярный формат обмена данными, называемый [JSON (JavaScript Object Notation)](https://python-all.ru/3.3/tutorial/inputoutput.html). Стандартный модуль [`json`](https://python-all.ru/3.3/library/json.html#module-json) принимает иерархии данных Python и преобразует их в строковые представления; этот процесс называется *сериализацией*. Восстановление данных из строкового представления называется *десериализацией*. Между сериализацией и десериализацией строка, представляющая объект, может быть сохранена в файле или данных, или отправлена по сетевому соединению на удалённую машину.304305> **Примечание**306>307> Формат JSON широко используется в современных приложениях для обмена данными. Многие программисты уже знакомы с ним, что делает его хорошим выбором для обеспечения совместимости.308309Если имеется объект `x`, можно просмотреть его JSON-строковое представление одной строкой кода:310311```python312>>> json.dumps([1, 'simple', 'list'])313'[1, "simple", "list"]'314```315316Другой вариант функции [`dumps()`](https://python-all.ru/3.3/library/json.html#json.dumps), называемый [`dump()`](https://python-all.ru/3.3/library/json.html#json.dump), просто сериализует объект в [*текстовый файл*](https://python-all.ru/3.3/glossary.html#term-text-file). Так, если `f` – это объект [*текстового файла*](https://python-all.ru/3.3/glossary.html#term-text-file), открытый для записи, можно сделать следующее:317318```python319json.dump(x, f)320```321322Чтобы снова декодировать объект, если `f` – это объект [*текстового файла*](https://python-all.ru/3.3/glossary.html#term-text-file), который был открыт для чтения:323324```python325x = json.load(f)326```327328Этот простой метод сериализации может обрабатывать списки и словари, но сериализация произвольных экземпляров классов в JSON требует дополнительных усилий. Справочная информация по модулю [`json`](https://python-all.ru/3.3/library/json.html#module-json) содержит объяснение этого.329330> **См. также**331>332> [`pickle`](https://python-all.ru/3.3/library/pickle.html#module-pickle) – модуль pickle333>334> В отличие от [*JSON*](https://python-all.ru/3.3/tutorial/inputoutput.html#tut-json), *pickle* – это протокол, позволяющий сериализовывать произвольно сложные объекты Python. Поэтому он специфичен для Python и не может использоваться для взаимодействия с приложениями, написанными на других языках. Кроме того, по умолчанию он небезопасен: десериализация данных pickle из ненадёжного источника может выполнить произвольный код, если данные были подготовлены опытным злоумышленником.335