Ключевые вопросы параграфа
- Что такое стандартный поток ввода и как с ним работать в Python?
- Какие методы позволяют считывать и записывать данные из текстовых файлов?
- Почему важно использовать менеджер контекста with при работе с файлами?
- Как устроен формат JSON и чем он отличается от обычного текста?
- Как использовать модуль json для чтения и записи структурированных данных?
Что такое стандартный поток ввода и как с ним работать в Python
Ранее вы уже использовали функцию input()
для чтения данных с клавиатуры. Этот способ хорош, если вы точно знаете, сколько строк нужно ввести или как выглядит строка для завершения ввода.
В таких случаях помогает стандартный поток ввода
— stdin
. Это поток, в который попадают все строки, вводимые пользователем. Программа может забирать их одну за другой, пока не достигнет конца ввода.
Подключение stdin
Чтобы использовать stdin
, его нужно импортировать:
1from sys import stdin
Поскольку stdin
— это итератор, по его строкам можно пройти в цикле:
1from sys import stdin
2
3lines = []
4for line in stdin:
5 lines.append(line)
6print(lines)
Запустим программу и введём следующие данные:
Первая Вторая Третья
Чтобы завершить ввод:
- в Windows — нажмите
Ctrl + Z
, затемEnter
; - в Linux и macOS — нажмите
Ctrl + D
.
Результат работы программы:
['Первая\n', 'Вторая\n', 'Третья\n']
Обратите внимание: каждая строка заканчивается символом перехода на новую строку (\n)
. Если он мешает, его можно удалить:
1from sys import stdin
2
3lines = []
4for line in stdin:
5 lines.append(line.rstrip("\n"))
6print(lines)
7
8# Теперь результат:
9# ['Первая', 'Вторая', 'Третья']
Чтение всех строк сразу
Если не нужен поэлементный перебор, можно считать все строки сразу с помощью readlines()
:
1from sys import stdin
2
3lines = stdin.readlines()
4print(lines)
Чтение всего ввода в одну строку
1from sys import stdin
2
3text = stdin.read()
4print([text])
5
6# Пример вывода:
7# ['Первая\nВторая\nТретья\n']
Здесь результат обёрнут в список, чтобы явно показать символы перехода на новую строку. Переменная text
содержит весь ввод целиком — со всеми символами \n
.
Какие методы позволяют считывать и записывать данные из текстовых файлов
Работа с файлами позволяет программам получать данные из внешних источников и сохранять результаты. Python предоставляет удобные инструменты для этого.
Что такое файл
Файл
— это именованная область данных на диске. Данные в нём хранятся как последовательность байтов
. Если файл текстовый, его можно интерпретировать как последовательность символов. Для корректной работы с символами нужно знать кодировку
(чаще всего используется UTF-8).
Функция open()
1open(file, mode='r', encoding=None)
Аргумент mode
определяет режим доступа к файлу:
'r'
— чтение (по умолчанию).
Файл должен существовать, иначе будет ошибка.'w'
— запись с очисткой содержимого.
Если файл существует, его содержимое удаляется. Если не существует — создаётся.'a'
— добавление в конец файла.
Новый текст будет дописан после уже имеющегося. Если файл не существует — создаётся.'r+'
— чтение и запись, без удаления содержимого.
Файл должен существовать. Запись идёт поверх существующего текста, начиная с начала файла.'w+'
— чтение и запись, с удалением содержимого.
Файл очищается или создаётся заново. Подходит, если вы хотите сначала записать, а потом прочитать.'a+'
— чтение и добавление.
Файл открывается в режиме добавления, но можно также его читать. При записи — курсор всегда в конце.
Важно: в Windows по умолчанию используется кодировка cp1251, поэтому нужно всегда явно указывать кодировку UTF-8, если вы хотите, чтобы программа работала кросс-платформенно.
Прочитать документацию вы можете по ссылке.
Пример: открытие файла для чтения
Допустим, у нас есть файл input_1.txt
, содержащий следующий текст:
1Привет!
2Это пример текстового файла.
3А это - последняя строка, которая заканчивается переходом на новую.
Прочитаем его содержимое:
1file_in = open("input_1.txt", encoding="UTF-8")
2for line in file_in:
3 print(line)
4file_in.close()
Построчное чтение файла
По открытому файлу можно пройти в цикле:
1file_in = open("input_1.txt", encoding="UTF-8")
2for line in file_in:
3 print(line)
4file_in.close()
Почему появляются пустые строки
Мы ожидали, что что строки выведутся одна под другой. Но фактически на экране будет:
1Привет!
2
3Это пример текстового файла.
4
5А это - последняя строка, которая заканчивается переходом на новую.
Причина: каждая строка из файла уже заканчивается символом переноса строки \n
, а функция print()
по умолчанию тоже добавляет \n
. В результате между строками получается двойной отступ.
Как это исправить
Можно удалить символ переноса в конце строки с помощью .rstrip("\n")
:
1print(line.rstrip("\n"))
Теперь вывод будет выглядеть так:
1Привет!
2Это пример текстового файла.
3А это - последняя строка, которая заканчивается переходом на новую.
Всё ровно — без лишних пустых строк.
Почему важно использовать менеджер контекста with при работе с файлами
Обычно после работы с файлом его нужно закрывать вручную:
1file_in = open("input_1.txt", encoding="UTF-8")
2# ... работа с файлом ...
3file_in.close()
Если этого не сделать, файл может остаться открытым:
- он будет заблокирован для других программ;
- данные могут не сохраниться сразу;
- при ошибке в коде close() может не выполниться вовсе.
Безопасный способ — использовать with
После работы с файлом его необходимо закрыть с помощью метода close()
. Это особенно важно, потому что:
- незакрытый файл может остаться заблокированным для других программ;
- данные могут не записаться полностью;
- при ошибке в программе вызов
close()
может не выполниться, и файл останется открытым.
Чтобы избежать этих проблем, используйте менеджер контекста — конструкцию with
. Она гарантирует, что файл будет закрыт автоматически, даже если в процессе работы произойдёт ошибка:
1with open("input_1.txt", encoding="UTF-8") as file_in:
2 for line in file_in:
3 print(line.rstrip("\n"))
Почему это ещё и быстрее
Следует помнить о том, что устройство хранения данных является самым медленным в компьютере, так что частые операции с файлами будут снижать скорость работы вашей программы.
Поэтому, если позволяют ресурсы компьютера (объём оперативной памяти), файл лучше прочитать сразу целиком, работать с ним в оперативной памяти и записывать в файл полностью полученный результат.
Чтение файла целиком — списком строк
Для получения полного списка строк текстового файла используется метод readlines()
:
1with open("input_1.txt", encoding="UTF-8") as file_in:
2 lines = file_in.readlines()
3print(lines)
4
5# Вывод программы:
6# ['Привет!\n', 'Это пример текстового файла.\n', 'А это -- последняя строка, которая должна закончиться переходом на новую.\n']
Чтение первых символов файла
Для чтения символов файла в строковую переменную используется метод read()
.
Прочитаем 10 символов файла:
1with open("input_1.txt", encoding="UTF-8") as file_in:
2 symbols = file_in.read(10)
3print([symbols])
4
5# Вывод программы:
6# ['Привет!\nЭт']
Если в методе read()
не указать количество считываемых символов, то прочитается весь файл.
Запись в файл
Для записи в файл его необходимо сначала открыть в режиме записи (выше мы говорили о режимах доступа).
Для записи данных из строковой переменной используется метод write()
:
1with open("output_1.txt", "w", encoding="UTF-8") as file_out:
2 n = file_out.write("Это первая строка\nА вот и вторая\nИ третья -- последняя\n")
3
4print(n)
Что делает программа:
- Открывает (или создаёт) файл
output_1.txt
в режиме записи. Если файл уже существует, его содержимое будет удалено. - Записывает в него одну строку с символами перевода строки
\n
внутри — это создаст три строки в файле. - Метод
write()
возвращает количество записанных символов, включая все пробелы и\n
. - Эта длина (в нашем случае —
55
) выводится в консоль.
Запись списка строк
Для записи строк из списка в файл используется метод writelines()
. Этот метод записывает строки в файл по очереди, без разделителя. Пример его использования:
1lines = ["Это первая строка\n", "А вот и вторая\n", "И третья - последняя\n"]
2with open("output_2.txt", "w", encoding="UTF-8") as file_out:
3 file_out.writelines(lines)
4
5# Содержимое выходного файла:
6# Это первая строка
7# А вот и вторая
8# И третья - последняя
Использование print()
для записи в файл
Функция print()
может быть использована для вывода данных в файл.
Для этого нужно передать ей в аргумент file
файловый объект:
1with open("output_3.txt", "w", encoding="UTF-8") as file_out:
2 print("Вывод в файл с помощью функции print()", file=file_out)
3
4# Содержимое выходного файла:
5# Вывод в файл с помощью функции print()
Как устроен формат JSON и чем он отличается от обычного текста
Существуют такие форматы текстовых файлов, которые могут хранить в себе информацию, структурированную по некоторым правилам.
Один из таких форматов — JSON
(англ. JavaScript Object Notation). Как видно из названия, он был создан для языка JavaScript, но в настоящее время независим от него и может использоваться практически с любым языком программирования.
Для значений в JSON можно использовать:
- строки — для обозначения строки используются строго двойные кавычки;
- числа — целые и вещественные;
- логические значения
true
иfalse
— записываются, в отличие от Python, со строчной буквы.
Для хранения неупорядоченных наборов данных в JSON можно использовать записи — пары «ключ: значение» (аналог словаря в Python). Также можно хранить упорядоченные последовательности значений (аналог списка в Python).
Посмотрим, что представляет собой JSON-файл, на примере. Предположим, что нужно хранить структурированную информацию о студентах следующего вида:
- фамилия (last_name),
- имя (first_name),
- отчество (patronymic),
- дата рождения (date_of_birth),
- номер группы (group_number),
- список номеров телефонов (phones_numbers).
Тогда список с информацией о студентах можно представить в следующем виде:
1[
2 {
3 "last_name": "Иванов",
4 "first_name": "Иван",
5 "patronymic": "Иванович",
6 "date_of_birth": "01.01.2001",
7 "group_number": 1,
8 "phone_numbers": [
9 "+7 111 111 1111",
10 "+7 111 111 1112"
11 ]
12 },
13 {
14 "last_name": "Петров",
15 "first_name": "Пётр",
16 "patronymic": "Петрович",
17 "date_of_birth": "10.10.2001",
18 "group_number": 1,
19 "phone_numbers": [
20 "+7 111 111 1113",
21 "+7 111 111 1114"
22 ]
23 }
24]
Мы видим, что в JSON-файле находится список из двух записей, очень похожих на словарь Python.
Как использовать модуль json
для чтения и записи структурированных данных
Для более удобной работы с JSON-файлами существует стандартный модуль json
.
Он позволяет преобразовать данные из JSON-файла в вашей программе в стандартные типы данных Python, а также способен выполнить обратную операцию — для записи данных обратно в файл.
Чтение JSON-файла
Для чтения JSON-файлов используется метод load()
, считывающий весь файл целиком и возвращающий объект стандартного типа данных Python:
1import json
2from pprint import pprint
3
4with open("data.json", encoding="UTF-8") as file_in:
5 records = json.load(file_in)
6pprint(records)
7
8#Вывод программы:
9# [{'date_of_birth': '01.01.2001',
10# 'first_name': 'Иван',
11# 'group_number': 1,
12# 'last_name': 'Иванов',
13# 'patronymic': 'Иванович',
14# 'phone_numbers': ['+7 111 111 1111', '+7 111 111 1112']},
15# {'date_of_birth': '10.10.2001',
16# 'first_name': 'Пётр',
17# 'group_number': 1,
18# 'last_name': 'Петров',
19# 'patronymic': 'Петрович',
20# 'phone_numbers': ['+7 111 111 1113', '+7 111 111 1114']}]
Из примера видно, что JSON-файл был преобразован в список словарей, а каждый словарь — это запись с информацией о студенте. Для обработки таких объектов можно применять стандартные методы и операции Python.
Запись JSON-файла
После того как вы изменили структуру данных в программе (например, обновили одно из полей словаря), результат можно сохранить обратно в JSON-файл.
Для этого используется метод dump() из модуля json. Он преобразует объект Python в строку в формате JSON и записывает её в файл.
Рассмотрим важные аргументы функции json.dump():
ensure_ascii
— еслиTrue
(по умолчанию), все не-ASCII-символы сохраняются как\uXXXX
. ПриFalse
сохраняются как есть (нужно для букв на кириллице).indent
— задаёт отступы для форматирования:None
(по умолчанию) — весь JSON в одну строку;- число — количество пробелов на уровень вложенности.
sort_keys
— если True, ключи в словаре будут отсортированы.
Пример
Изменим поле group_number
у второго студента и запишем обновлённые данные обратно в файл:
1import json
2
3with open("data.json", encoding="UTF-8") as file_in:
4 records = json.load(file_in)
5records[1]["group_number"] = 2
6with open("data.json", "w", encoding="UTF-8") as file_out:
7 json.dump(records, file_out, ensure_ascii=False, indent=2)
Содержимое файла data.json
после работы программы:
1[
2 {
3 "last_name": "Иванов",
4 "first_name": "Иван",
5 "patronymic": "Иванович",
6 "date_of_birth": "01.01.2001",
7 "group_number": 1,
8 "phone_numbers": [
9 "+7 111 111 1111",
10 "+7 111 111 1112"
11 ]
12 },
13 {
14 "last_name": "Петров",
15 "first_name": "Пётр",
16 "patronymic": "Петрович",
17 "date_of_birth": "10.10.2001",
18 "group_number": 2,
19 "phone_numbers": [
20 "+7 111 111 1113",
21 "+7 111 111 1114"
22 ]
23 }
24]
Преобразование ключей словаря
Модуль json
автоматически преобразует ключи словаря в строки, если они были, например, целыми числами.
Рассмотрим пример:
1import json
2
3records = {
4 1: "First",
5 2: "Second",
6 3: "Third"
7}
8
9with open("output.json", "w", encoding="UTF-8") as file_out:
10 json.dump(records, file_out, ensure_ascii=False, indent=2)
Содержимое файла output.json
после работы программы:
1{
2 "1": "First",
3 "2": "Second",
4 "3": "Third"
5}
Обратите внимание: ключи 1, 2, 3 были целыми числами в Python, но в JSON все ключи обязательно должны быть строками — они были автоматически преобразованы при записи.
✅ У вас получилось разобраться, как работать с файлами и JSON в Python?
Что дальше
Теперь вы умеете считывать данные из стандартного потока ввода, читать и записывать текстовые файлы, работать с кодировкой, а также обрабатывать структурированные данные в формате JSON. Вы познакомились с менеджером контекста with
, поняли, как важно закрывать файл, и научились использовать модуль json
для преобразования данных.
Далее — финальный параграф третьей главы, в котором мы кратко подведём итоги.
А пока вы не ушли дальше — закрепите материал на практике:
- Отметьте, что урок прочитан, при помощи кнопки ниже.
- Пройдите мини-квиз, чтобы проверить, насколько хорошо вы усвоили тему.
- Перейдите к задачам этого параграфа и потренируйтесь.
- Перед этим загляните в короткий гайд о том, как работает система проверки.
Хотите обсудить, задать вопрос или не понимаете, почему код не работает? Мы всё предусмотрели — вступайте в сообщество Хендбука! Там студенты помогают друг другу разобраться.
Ключевые выводы параграфа
- Стандартный поток ввода
stdin
позволяет считывать произвольное количество строк из консоли, что удобно при обработке входных данных без заранее известного объёма. - С помощью методов
read()
,readlines()
иwrite()
можно считывать и записывать данные из текстовых файлов, построчно или целиком. - Менеджер контекста
with
гарантирует, что файл будет закрыт автоматически, даже если в программе произойдёт ошибка. - Формат JSON используется для хранения структурированных данных и поддерживается большинством языков программирования, включая Python.
- Модуль
json
позволяет легко преобразовывать JSON-файлы в объекты Python (load
) и обратно (dump
), а также управлять форматированием и кодировкой при записи.