Исправление ошибки кодировки при запуске скриптов Python из-за не-UTF-8 символов
Причины и основные способы устранения ошибки
Ошибка кодировки 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) # корректно отображается
Иван Мария