Текстовые файлы: кодировки и разбор текста

В предыдущей статье мы разобрали основы работы с файлами. Здесь — то, что касается именно текста: кодировки и разбор содержимого построчно.

Кодировки

На диске файл — это просто последовательность байтов. Чтобы из них получились буквы, нужно знать, по какой схеме переводить байты обратно в символы. Эта схема и называется кодировкой, а придумано их много: разные языки исторически получили разные.

Современный стандарт — UTF-8: он покрывает все алфавиты мира разом, включая эмодзи 😊. Правило для новичка простое: писать и читать в UTF-8, указывая кодировку явно параметром encoding.

Python 3.13
text = "Привет, мир! Hello, world!"

with open('text_utf8.txt', 'w', encoding='utf-8') as file:
    file.write(text)

with open('text_utf8.txt', 'r', encoding='utf-8') as file:
    print(file.read())
Привет, мир! Hello, world!

Проблемы начинаются, когда кодировки не совпали: файл записан по одной схеме, а читают его по другой. Попробуем прочитать наш файл как ascii — старую кодировку, в которой есть только латиница, цифры и знаки препинания:

Python 3.13
with open('text_utf8.txt', 'w', encoding='utf-8') as file:
    file.write("Привет, мир! Hello, world!")

try:
    with open('text_utf8.txt', 'r', encoding='ascii') as file:
        print(file.read())
except UnicodeDecodeError as e:
    print(f"Ошибка декодирования: {e}")
Ошибка декодирования: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)

Первый же байт кириллической буквы не укладывается в ascii, и Python останавливается с UnicodeDecodeError. Обратная ситуация выглядит так же: если записывать кириллицу в кодировку, которая её не знает, будет ошибка UnicodeEncodeError.

Конструкция try/except здесь нужна лишь для того, чтобы программа не оборвалась на ошибке. Ей посвящён отдельный урок дальше в курсе, так что сейчас вникать в неё не обязательно.

Разбираем конфигурационный файл

Настройки программ часто хранят в текстовом файле: каждая строка — пара «ключ = значение». Ниже два файла рядом: config.ini с настройками и main.py, который собирает из них словарь.

main.py
1def read_config(filename):2  config = {}3 4  with open(filename, 'r', encoding='utf-8') as file:5      for line in file:6          key, value = line.split('=', 1)  # режем только по первому '='7          config[key.strip()] = value.strip()8 9  return config10 11 12settings = read_config('config.ini')13 14print(settings)15print(f"Тема оформления: {settings['theme']}, язык: {settings['language']}")16 

Запустим main.py — в выводе:

{'theme': 'dark', 'language': 'ru', 'autosave': 'True'}
Тема оформления: dark, язык: ru

Проверка понимания

Файл записан в UTF-8, а открыли его с encoding='ascii'. Что произойдёт?

В следующей статье посмотрим структурированные форматы данных — JSON и CSV.