Python encoding problem utf8

Ошибки при конвертации#

При конвертации между строками и байтами очень важно точно знать, какая кодировка используется, а также знать о возможностях разных кодировок.

Например, кодировка ASCII не может преобразовать в байты кириллицу:

In [32]: hi_unicode = 'привет' In [33]: hi_unicode.encode('ascii') --------------------------------------------------------------------------- UnicodeEncodeError Traceback (most recent call last) ipython-input-33-ec69c9fd2dae> in module>() ----> 1 hi_unicode.encode('ascii') UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128) 

Аналогично, если строка «привет» преобразована в байты, и попробовать преобразовать ее в строку с помощью ascii, тоже получим ошибку:

In [34]: hi_unicode = 'привет' In [35]: hi_bytes = hi_unicode.encode('utf-8') In [36]: hi_bytes.decode('ascii') --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) ipython-input-36-aa0ada5e44e9> in module>() ----> 1 hi_bytes.decode('ascii') UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128) 

Еще один вариант ошибки, когда используются разные кодировки для преобразований:

In [37]: de_hi_unicode = 'grüezi' In [38]: utf_16 = de_hi_unicode.encode('utf-16') In [39]: utf_16.decode('utf-8') --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) ipython-input-39-4b4c731e69e4> in module>() ----> 1 utf_16.decode('utf-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte 

Наличие ошибок — это хорошо. Они явно говорят, в чем проблема. Хуже, когда получается так:

In [40]: hi_unicode = 'привет' In [41]: hi_bytes = hi_unicode.encode('utf-8') In [42]: hi_bytes Out[42]: b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82' In [43]: hi_bytes.decode('utf-16') Out[43]: '뿐胑룐닐뗐苑' 

Обработка ошибок#

У методов encode и decode есть режимы обработки ошибок, которые указывают, как реагировать на ошибку преобразования.

Параметр errors в encode#

По умолчанию encode использует режим strict — при возникновении ошибок кодировки генерируется исключение UnicodeError. Примеры такого поведения были выше.

Вместо этого режима можно использовать replace, чтобы заменить символ знаком вопроса:

In [44]: de_hi_unicode = 'grüezi' In [45]: de_hi_unicode.encode('ascii', 'replace') Out[45]: b'gr?ezi' 

Или namereplace, чтобы заменить символ именем:

In [46]: de_hi_unicode = 'grüezi' In [47]: de_hi_unicode.encode('ascii', 'namereplace') Out[47]: b'gr\\Nezi' 

Кроме того, можно полностью игнорировать символы, которые нельзя закодировать:

In [48]: de_hi_unicode = 'grüezi' In [49]: de_hi_unicode.encode('ascii', 'ignore') Out[49]: b'grezi' 

Параметр errors в decode#

В методе decode по умолчанию тоже используется режим strict и генерируется исключение UnicodeDecodeError.

Если изменить режим на ignore, как и в encode, символы будут просто игнорироваться:

In [50]: de_hi_unicode = 'grüezi' In [51]: de_hi_utf8 = de_hi_unicode.encode('utf-8') In [52]: de_hi_utf8 Out[52]: b'gr\xc3\xbcezi' In [53]: de_hi_utf8.decode('ascii', 'ignore') Out[53]: 'grezi' 

Режим replace заменит символы:

In [54]: de_hi_unicode = 'grüezi' In [55]: de_hi_utf8 = de_hi_unicode.encode('utf-8') In [56]: de_hi_utf8.decode('ascii', 'replace') Out[56]: 'gr��ezi' 

Источник

Python encoding problem utf8

Быстрое, но не всегда работающее решение

Вначале скрипта надо прописать:

Соответственно, сам текст скрипта должен быть в кодировке UTF-8.

Но не все так просто. В Python 2.7.x, даже если прописать эту строку в начало файла с исходником, даже если все файлы с исходниками будут в кодировке UTF-8, то не исключена ситуация, что всеравно появится ошибка:

UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xd0 in position 0: ordinal not in range(128)

В куче статей, которыми наполнен интернет, почему-то предлагаются частные решения этой глобальной проблемы. Предлагают использовать запись строк с буквой u в начале: u»Это строка» . Другой предлагаемый метод — е сли у вас встречаются строки на русском языке или с кириллическими символами, перекодируйте их в юникод с помощью встроенного в строку метода decode() :

Но такой метод решения проблем — это все равно что вилкой копать скалу. Исковыряете весь код лишними строками, а проблема как была так и останется.

Однако решение все-таки есть

В начале модуля, в котором возникает ошибка, надо прописать:

# Устранение проблем с кодировкой UTF-8

И ошибка кодировки исчезнет.

  • Использование UTF-8 в Python, устранение проблем с кодировкой
  • Основные конструкции языка Python
  • Пример стиля форматирования в Python
  • Оператор pass
  • Цикл с постусловием в Python
  • Как выйти из Python программы с кодом завершения
  • Python: пример открытия файла и перебора строк в нём
  • Python: работа со строками
  • Python: работа со списками
  • Python: тип данных bool и операторы сравнения
  • Python: запуск внешних программ и команд
  • Python: запуск внешней программы или команды
  • Работа с директориями и файлами в Python
  • Регулярные выражения в Python, простой пример
  • Python: выход из программы с кодом возврата
  • Python: преобразования типов, определение типа переменной
  • Python: списки, кортежи, словари
  • Аналог PHP-функции trim() в Python
  • Глобальные переменные в языке Python
  • Руководство по магическим методам в Питоне
  • Как в Python подсчитать количество страниц в PDF-файле
  • Основы языка программирования Python за 10 минут
  • Импорт скриптов (библиотек) в Python
  • Функции с неизвестным числом аргументов в Python и параметры по умолчанию
  • Классы в Python для PHP-разработчиков
  • Сериализация объектов в Python
  • Как в Python получить UNIX Timestamp
  • Особенности импорта модулей в Python
  • О порядке поиска пакетов и модулей для импорта в Python
  • Сводная таблица методов для базовых типов Python2 и Python3
  • Наследование в Python — краткое пояснение
  • Как в Python вызвать метод того же класса
  • Курс «Программирование на Python» от преподавателей СПбАУ РАН и ИТМО
  • Бесплатный курс pythontutor.ru (Питонтьютор)
  • Краткое описание библиотеки math
  • Как установить пакет PIP на компьютере без сети Интернет
  • Лямбда-функции в языке Python. Использование map/filter/reduce. Простое объяснение
  • Как настроить запуск главного скрипта в Python-проекте в VSCode
  • Как в VSCode в проекте на Python обеспечить навигацию по коду
  • Как в Python вызвать метод объекта по имени, которое написано в виде строковой переменной?
  • 10 ловушек в Python
  • 10 хитростей Python, о которых полезно знать
  • Django: основы работы

Источник

Проблемы с кодировкой в Python

10 февраля 2013 г. Archy Просмотров: 50782 RSS 4
Запуск программ на Python » Python и запуск програм python unicode, python utf-8, python windows-1251, python кодировка

В python есть 2 объекта работающими с текстом: unicode и str, объект unicode хранит символы в формате (кодировке) unicode, объект str является набором байт/символов в которых python хранит остальные кодировки (utf8, cp1251, cp866, koi8-r и др).

Кодировку unicode можно считать рабочей кодировкой питона т.к. она предназначена для её использования в самом скрипте — для разных операций над строками.

Внешняя кодировка (объект str) предназначена для хранения и передачи текстовой информации вне скрипта, например для сохранения в файл или передачи по сети. Поэтому в данной статье я её назвал внешней. Самой используемой кодировкой в мире является utf8 и число приложений переходящих на эту кодировку растет каждый день, таким образом превращаясь в «стандарт».

Эта кодировка хороша тем что для хранения текста она занимает оптимальное кол-во памяти и с помощью её можно закодировать почти все языки мира ( в отличие от cp1251 и подобных однобайтовых кодировок). Поэтому рекомендуется везде использовать utf8, и при написании скриптов.

Использование

Скрипт питона, в самом начале скрипта указываем кодировку файла и сохраняем в ней файл

для того что-бы интерпретатор python понял в какой кодировке файл

Строки в скрипте

Строки в скрипте хранятся байтами, от кавычки до кавычки:

Если перед строкой добавить символ u, то при запуске скрипта, эта байтовая строка будет декодирована в unicode из кодировки указанной в начале :

и если кодировка содержимого в файле отличается от указанной, то в строке могут быть «битые символы»

Загрузка и сохранение файла

# coding: utf8 # Загружаем файл с кодировкай utf8 text = open('file.txt','r').read() # Декодируем из utf8 в unicode - из внешней в рабочую text = text.decode('utf8') # Работаем с текстом text += text # Кодируем тест из unicode в utf8 - из рабочей во внешнюю text = text.encode('utf8') # Сохраняем в файл с кодировкий utf8 open('file.txt','w').write(text)

Текст в скрипте

# coding: utf8 a = 'Текст в utf8' b = u'Текст в unicode' # Эквивалентно: b = 'Текст в unicode'.decode('utf8') # т.к. сам скрипт хранится в utf8 print 'a =',type(a),a # декодируем из utf-8 в unicode и далее unicode в cp866 (кодировка консоли winXP ru) print 'a2 =',type(a),a.decode('utf8').encode('cp866') print 'b =',type(b),b

Процедуре print текст желательно передавать в рабочей кодировке либо кодировать в кодировку ОС.

Результат скрипта при запуске из консоли windows XP:

В последней строке print преобразовал unicode в cp866 автоматический, см. следующий пункт

Авто-преобразование кодировки

В некоторых случаях для упрощения разработки python делает преобразование кодировки, пример с методом print можно посмотреть в предыдущем пункте.

В примере ниже, python сам переводит utf8 в unicode — приводит к одной кодировке для того что-бы сложить строки.

# coding: utf8 # Устанавливаем стандартную внешнюю кодировку = utf8 import sys reload(sys) sys.setdefaultencoding('utf8') a = 'Текст в utf8' b = u'Текст в unicode' c = a + b print 'a =',type(a),a print 'b =',type(b),b print 'c =',type(c),c

Результат

c = Текст в utf8Текст в unicode

Как видим результирующая строка «c» в unicode. Если бы кодировки строк совпадали то авто-перекодирования не произошло бы и результирующая строка содержала кодировку слагаемых строк.

Авто-перекодирование обычно срабатывает когда происходит взаимодействие разных кодировок.

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

# coding: utf8 # Устанавливаем стандартную внешнюю кодировку = utf8 import sys reload(sys) sys.setdefaultencoding('utf8') print '1. utf8 and unicode', 'true' if u'Слово'.encode('utf8') == u'Слово' else 'false' print '2. utf8 and cp1251', 'true' if u'Слово'.encode('utf8') == u'Слово'.encode('cp1251') else 'false' print '3. cp1251 and unicode', 'true' if u'Слово'.encode('cp1251') == u'Слово' else 'false'

Результат

script.py:10: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode — interpreting them as being unequal

print ‘3. cp1251 and unicode’, ‘true’ if u’Слово’.encode(‘cp1251′) == u’Слово’ else ‘false’

3. cp1251 and unicode false

В сравнении 1, кодировка utf8 преобразовалась в unicode и сравнение произошло корректно.

В сравнении 2, сравниваются кодировки одного вида — обе внешние, т.к. кодированы они в разных кодировках условие выдало что они не равны.

В сравнении 3, выпало предупреждение из за того что выполняется сравнение кодировок разного вида — рабочая и внешняя, а авто-декодирование не произошло т.к. стандартная внешняя кодировка = utf8, и декодировать строку в кодировке cp1251 методом utf8 питон не смог.

Вывод списков

# coding: utf8 d = ['Тест','списка'] print '1',d print '2',d.__repr__() print '3',','.join(d)

Результат:

1 [‘\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82’, ‘\xd1\x81\xd0\xbf\xd0\xb8\xd1\x81\xd0\xba\xd0\xb0’]

2 [‘\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82’, ‘\xd1\x81\xd0\xbf\xd0\xb8\xd1\x81\xd0\xba\xd0\xb0’]

При выводе списка, происходит вызов []() который возвращает внутреннее представление этого спиcка — print 1 и 2 являются аналогичными. Для корректного вывода списка, его нужно преобразовать в строку — print 3.

Установка внешней кодировки при запуске

PYTHONIOENCODING=utf8 python 1.py

В обучении ребенка важно правильное толкование окружающего его мира. Существует масса полезных журналов которые начнут экологическое воспитание дошкольников правильным путем. Развивать интерес к окружающему миру очень трудный но интересный процесс, уделите этому особое внимание.

Источник

Читайте также:  Что такое флекс css
Оцените статью