Исправление ошибки кодировки при запуске скриптов Python из-за не-UTF-8 символов

Раздел: Основы Python -> Ошибки Python

Причины и основные способы устранения ошибки

Ошибка кодировки UTF-8 возникает, когда интерпретатор Python обнаруживает в исходном файле байты, которые не являются допустимыми в кодировке UTF-8. Это часто случается, если файл сохранен в однобайтовой кодировке (например, cp1251, latin-1) и содержит символы, не входящие в ASCII.

Как указать кодировку исходного файла явно?

Наиболее эффективное решение - добавить в первую или вторую строку файла специальный комментарий, объявляющий кодировку. Этот комментарий должен быть оформлен как # -*- coding: <encoding> -*- или # coding: <encoding>.


# -*- coding: cp1251 -*-
print('Привет, мир!')
  

Python attributeerror object has no attribute (ошибка attributeerror в python)

После этого интерпретатор будет читать файл как cp1251. Важно, чтобы сам файл действительно был сохранен в этой кодировке. Если кодировка отличается, ошибка сохранится.

Типичные проблемы:

  • Пробел между # и coding - допускается, но некоторые старые версии могут требовать точного формата # -*- coding: ... -*-.
  • Если комментарий стоит не в первой или второй строке, он игнорируется.
  • Неверно указано имя кодировки (например, utf8 вместо utf-8).

Как преобразовать файл в кодировку UTF-8?

Если исходный файл не требуется сохранять в cp1251, его можно перекодировать в UTF-8. Это можно сделать через редактор (например, Notepad++: меню «Кодировки» → «Преобразовать в UTF-8») или командой в Linux/macOS с помощью iconv.


iconv -f WINDOWS-1251 -t UTF-8 input.py > output.py
  

Non utf 8 code starting with python (ошибка кодировки utf-8 в python)

После конвертации объявление кодировки можно убрать, так как UTF-8 является кодировкой по умолчанию для Python 3.

Возможные проблемы:

  • При копировании файла могут потеряться символы, не представимые в UTF-8 (редко, но возможно).
  • iconv может не справиться с искажёнными байтами - тогда нужно использовать -c для игнорирования ошибок.

Как правильно читать файлы данных в не-UTF-8 кодировке?

Ошибка может возникать не при запуске скрипта, а при чтении внешнего файла. В этом случае следует указывать кодировку в функции open().


with open('data.txt', 'r', encoding='cp1251') as f:
    content = f.read()
    print(content)
  

Python exit code 9009 (ошибка python с кодом 9009)

Этот подход безопаснее, чем глобальное изменение кодировки, и позволяет работать с разными файлами в разных кодировках в одном скрипте.

Частая ошибка:

  • Забыть указать encoding - тогда Python использует системную кодировку (часто UTF-8), что приводит к UnicodeDecodeError.
  • Использование encoding='utf-8' для файла в cp1251 снова вызовет ошибку.

Как настроить редактор для автоматического сохранения в UTF-8?

Чтобы избежать проблемы в будущем, удобно настроить редактор кода на сохранение файлов в UTF-8. В PyCharm: File → Settings → Editor → File Encodings → установить UTF-8 для всех пунктов. В VS Code: в settings.json добавить "files.encoding": "utf8".


// VS Code settings.json
{
    "files.encoding": "utf8",
    "files.autoGuessEncoding": false
}
  

Примечание:

  • Если проект уже содержит файлы в cp1251, их потребуется пересохранить вручную.

Почему не стоит использовать sys.setdefaultencoding?

Некоторые старые гайды предлагают вызывать sys.setdefaultencoding('cp1251'). Этот метод удалён из Python 3, а в Python 2 его использование приводило к непредсказуемым ошибкам и считается опасным.


import sys
reload(sys)
sys.setdefaultencoding('cp1251')  # Не делайте так!
  

Последствия:

  • Изменение глобальной кодировки может сломать работу с библиотеками, ожидающими UTF-8.
  • В Python 3 этот код вызовет исключение AttributeError.

Расширенные примеры с детальными пояснениями

Демонстрация ошибки и её исправление

Создадим файл example.py, сохранённый в кодировке cp1251, содержащий кириллицу. При запуске без объявления кодировки возникает синтаксическая ошибка.

Пример

# example.py (файл в cp1251)
print('Привет')
$ python example.py
  File "example.py", line 1
SyntaxError: Non-UTF-8 code starting with '\xcf' in file example.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Добавим в начало файла объявление кодировки:

Пример

# -*- coding: cp1251 -*-
print('Привет')
$ python example.py
Привет

Работа с файлами разных кодировок

Допустим, есть CSV-файл в cp1251 с разделителем-запятой. Прочитаем его корректно:

Пример

import csv

with open('data_cp1251.csv', 'r', encoding='cp1251') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)
['Имя', 'Возраст']
['Анна', '25']
['Пётр', '30']

Если бы кодировка не была указана, Python попытался бы прочитать как UTF-8 и выбросил бы UnicodeDecodeError.

Обнаружение кодировки с помощью chardet

Когда кодировка файла неизвестна, можно воспользоваться библиотекой chardet для её определения:

Пример

import chardet

with open('unknown.txt', 'rb') as f:
    raw = f.read()
    result = chardet.detect(raw)
    print(result)
    decoded = raw.decode(result['encoding'])
    print(decoded)
{'encoding': 'ISO-8859-1', 'confidence': 0.73}
... (содержимое файла)

Затем можно передать обнаруженную кодировку в open().

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

Если внутри скрипта получена строка в cp1251, её можно перевести в UTF-8:

Пример

byte_data = b'\xcf\xf0\xe8\xe2\xe5\xf2'  # 'Привет' в cp1251
corrected = byte_data.decode('cp1251').encode('utf-8')
print(corrected.decode('utf-8'))
Привет

Исправление ошибки при работе с базами данных

При подключении к MySQL, где таблица использует cp1251, необходимо указать кодировку в параметрах соединения:

Пример

import mysql.connector

conn = mysql.connector.connect(
    host='localhost',
    database='test',
    charset='cp1251'
)
cursor = conn.cursor()
cursor.execute('SELECT name FROM users')
for (name,) in cursor:
    print(name)  # корректно отображается
Иван
Мария

Ошибка кодировки UTF-8 в Python - comments

En
Non utf 8 code starting with python (python)