Как сделать кодировку utf 8 в python

Добавил пользователь Владимир З.
Обновлено: 04.10.2024

Многие уже знают, что для хранения числовых и текстовых данных в памяти вашего компьютера используются последовательности кодов. Каждая буква записывается как элемент кода в вычислительную память, а при отображении она конвертируется обратно. Очень долгое время, начиная с 60-х годов прошлого века использовался стандарт American Standard Code for Information Interchange или, сокращенно — ASCII. Несмотря на все последующие модификации стандарта, он упёрся в ограничение 256 символов, что, с учетом развития алфавитов многих стран, стало катастрофически мало

ASCII на сегодняшний день используется в крайне редких случаях.

Что такое Unicode?

Unicode — это относительно новый стандарт кодирования, который сейчас повсеместно используется в программировании. Принцип Unicode в диапазоне-последовательности кодовых точек, к которым привязаны определенные символы (буквы, цифры, знаки препинания и т.д.). Кодовое пространство стандарта включает 1 114 112 кодовых точек, находящихся в пределах 0-10FFFF.

Для работы с данными в Unicode принято использовать правило Unicode sandwich — байты из памяти конвертируются в строковый формат (Uncode). Дальше в приложении данные оперируются только в строковом формате. Перед передачей данных мы снова конвертируем строку в байты


Кодировка UTF-8

Чтобы передавать данные по сети нам нужно сконвертировать текст в байты. Для этого и служит одна из версий Unicode — кодировка UTF-8. Она имеет переменную длину кода — это значит, что UTF-8 не использует один байт все время, это от 1 до 4 байтов.

Unicode в Python

Итак, мы определились. Для человека текст — это набор соответствующих символов. Для памяти компьютера — это данные в виде байт. Если это представить через призму языка программирования Python, то мы получим следующее:

  • Тип данных str — это текст, он же неизменяемый набор кодов (code points) Unicode;
  • Тип данных bytes — это данные (байты), это же неизменяемый набор байтов

Строки


Байты

Байты в среде разработки Python — это тоже последовательность unicode-символов, но, в отличии от строк, представлены в виде ASCII, а это значит, что при работе с кириллицей будет ошибка. Байтовый тип данных в питоне маркируется английской буквой b

Результат (ошибки нет, т.к. этот участок кода закомментирован):


Конвертация (decode, encode)

Практически все программы так или иначе работают с сетью или файловой системой, поэтому работа с байтами так или иначе необходима. Чтобы преобразовывать байты в строки (bytes -> str) и наоборот (str -> bytes) используются методы кодирования или декодирования.


Методы encode и decode можно применять к типам данных str и bytes. В качестве аргумента передается имя переменной и ключ шифрования (кодировка, если по-простому).

Файловая система и кодировка

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

def_coding = locale.getpreferredencoding()
print(def_coding)


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

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


Модуль subprocess

В этом примере результат работы модуля subprocess — это конвертация каждой из строк в формат кодировки cp866, после чего результат перекодируется в UTF-8. Он представляет собой набор кодов Unicode (байтовый формат). Для дальнейшей работы с результатом как со строкой необходимо преобразовать его в этот тип, то есть выполнить операцию decode.


Возникают вопросы: что происходит, кто виноват? Ответ не будет коротким.

1. Компьютер – человек

Так сложилось, что компьютерная техника оперирует единицами и нулями. На вашей же клавиатуре представлено не менее 100 клавиш. Все, что вы вводите при печати, в итоге преобразуется в те самые бинарные величины.

2. ASCII

Так как первые вычислительные машины были малоемкими, для представления в их памяти всего набора требуемых знаков хватало 7 бит (или 128 символов). Сюда входил весь английский алфавит в верхнем и нижнем регистрах, цифры, знаки, вспомогательные символы.

С другими свойствами модуля можете ознакомиться самостоятельно.

Потребовалось указание кодировок в заголовках документов.

3. Юникод-стандарт

Пытался тупо перебрать варианты (в консоль оно так же пишет бред):



было бы нелишним указать версию питона


Было бы неплохо получить общее решение для 2.7 и 3. Но это 2.7, так как скрипт вообще еще не пашет в 3 - нужны будут правки, а я до этого еще не добрался.


а приходит в какой кодировке?


Из js в utf-8 полюбому.


выводит тo же самое, что и

MyTrooName ★★★★★ ( 21.07.14 06:24:36 )
Последнее исправление: MyTrooName 21.07.14 06:24:50 (всего исправлений: 1)


Абсолютно то же самое. Может проблема еще при разборе параметров. Я не уверен. Это первый мой опыт с python - пытаюсь переписать вэб-интерфейс для Cementine. Уже перетащил на ajax, много чего выправил. А вот эту траблу не могу решить (это сохранение плейлиста). Оно и в оригинале так работало разумеется.





ну, с setsystemencoding exception не вылетит, но результат все равно отличается

это -*- coding: utf-8 и это reload(sys) sys.setdefaultencoding('utf8') - не нужно


а вот универсальный код (для py3 и py2):

благодарности присылать не надо :-)


О, пляски с бубном. Как мило. Что за фреймворк? Ты уверен что приложение крутится под правильной локалью?


__builtins__ лучше не использовать. И вообще getattr(__builtins__, 'unicode', str)


ну и . быть может — тогда уж и старенький python2 лучше не использовать? :-)

И вообще getattr(__builtins__, 'unicode', str)

user_id_68054 ★★★★★ ( 21.07.14 08:59:23 )
Последнее исправление: user_id_68054 21.07.14 09:00:57 (всего исправлений: 3)


__builtins__ лучше не использовать

тогда предлагаю на обсуждение ещё вариант:

user_id_68054 ★★★★★ ( 21.07.14 09:08:23 )
Последнее исправление: user_id_68054 21.07.14 09:09:27 (всего исправлений: 2)


The value of __builtins__ is normally either this module or the value of this modules’s __dict__ attribute.


Это все не имеет смысла, так как проблема ТС в другом. 70% что у него косые данные приходят от клиента.


ещё думаю проблема что ТС в том что у него несколько проблем, а он возможно считает что проблема только одна

на каком разделе создается файл?

что выводит print(listName)?

конечно не надо, вед.


нет. просто всё потому что я скромняшка :)



И тоже нет. Ни один из рецептов не помог.

А куски кода будут?


Вот парсинг POST (просто слямзил откуда-то):


Что, если попробовать:


Это самое первое что попробовал - нет (((

Да, мне очень не нравится этот кустарный веб-сервер. Почему бы не взять что-то вроде web.py, Bottle, CherryPy?


Да, блин чо было, то и взял. Я там по большому счету добавил только do_POST. Первый раз python вижу.

Ну и перепилил web на отдачу json чтобы все по ajax работало, да починил отдачу ресурсов. И выкорчевал html из кода в отдельный html-файл. Сейчас еще переверстаю, чтобы мне для телика подходило и это будет все что мне от него надо ;)

Этот документ (PEP 263 [1]) представляет синтаксис для декларации кодировки текста в файле исходного кода на языке Python. Информация о кодировке затем используется парсером Python для интерпретации файла на указанной кодировке. Прежде всего это улучшает интерпретацию литералов Unicode в исходном коде, и делает возможным писать в литералах Unicode с использованием например UTF-8 напрямую в редакторе, поддерживающем Unicode.

Описываемый ниже метод позволяет избежать ошибок наподобие:

Python source file encoding error

Процесс по шагам:

1. Проверьте, что текст модуля Python сохранен в кодировке UTF-8. В редакторе Notepad2 это делается через меню File -> Encoding. Этот же пункт меню позволяет перекодировать файл в кодировку UTF-8.

2. Добавьте в начало модуля строку:

После этого ошибка исчезнет.

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

Чтобы настроить Python для распознавания этой декларации кодировки, необходимо ознакомиться о принципах обработки данных исходного кода Python.

[Определение кодировки]

По умолчанию Python подразумевает, что в файле принят стандарт кодирования ASCII, если не дано никаких других подсказывающих указаний. Чтобы определить кодировку исходного кода, во все исходные файлы нужно добавить "магический" комментарий в первой или второй строке исходного файла:

или (используя форматы, распознаваемые популярными редакторами):

Если быть более точным, то первая или вторая строка должна попадать под фильтр следующего регулярного выражения:

Первая группа этого выражения интерпретируется как имя кодировки. Если эта кодировка не известна для Python, то во время попытки компиляции произойдет ошибка. Не должно быть никакого любого оператора Python в строке, в этой строке, где содержится декларация о кодировке. Если на первую строку регулярное выражение сработает, то вторая строка на предмет поиска кодировки игнорируется.

Чтобы обработать такие платформы, как Windows, которые добавляют маркеры Unicode BOM в начало файла Unicode, UTF-8 сигнатура \xef\xbb\xbf будет также интерпретироваться как кодировка 'utf-8' (даже если в файл не добавлен описанный магический комментарий).

Если исходный файл использует одновременно сигнатуру маркера UTF-8 BOM, и магический комментарий, то разрешенной кодировкой для комментария будет только 'utf-8'. Любая другая кодировка в этом случае приведет к ошибке.

[Примеры]

Ниже приведено несколько примеров, показывающих разные стили определения кодировки исходного кода в начале файла Python.

1. Двоичный интерпретатор и использование файла стиля Emacs:

2. Без строки интерпретатора, используя чистый текст:

3. Текстовые редакторы могут иметь разные способы определения кодировки файла, например:

4. Без комментария кодировки парсер Python подразумевает, что это текст ASCII:

[Плохие примеры]

Ниже для полноты приведены ошибочные комментарии для указания кодировки, которые не будут работать.

A. Пропущенный префикс "coding:":

B. Комментарий кодировки не находится на строке 1 или 2:

C. Не поддерживаемая кодировка:

PEP [1] основывается на следующих концепциях, которые должны быть реализованы, чтобы включить использование такого "магического" комментария:

1. Во всем исходном файле Python должна использоваться одинаковая кодировка. Встраивание по-другому закодированных данных приведет к ошибке декодирования на этапе компиляции исходного файла кода Python.

Можно использовать в исходном коде любое кодирование, которое позволяет обработать две первые строки способом, показанным выше, включая ASCII-совместимое кодирование, а также определенные многобайтовые кодировки, такие как Shift_JIS. Это не включает кодировки наподобие UTF-16, которые используют два или большее количество байтов для всех символов. Причина в том, что требуется сохранять простым алгоритм декодирования кодировки в парсере ключевых слов (токенизатор).

3. Комбинация токенизатор/компилятор Python должна быть обновлена, чтобы работать следующим образом:

Обратите внимание, что идентификаторы Python ограничены подмножеством кодирования ASCII, так что других преобразований не потребуется.

Для обратной совместимости с существующим кодом, который в нестоящее время использует не-ASCII кодировку в строковых литералах без декларации кодирования, реализация будет представлена двумя фразами:

1. Разрешается использование не-ASCII кодировки в строковых литералах и комментариях, при этом внутренне будет рассматриваться отсутствие объявление кодировки как декларация "iso-8859-1". В результате произвольная строка байт будет корректно обработана с предоставлением совместимости с Python 2.2 для литералов Unicode, которые содержат байты, не попадающие в кодировку ASCII.

Будут выдаваться предупреждения по мере появления non-ASCII байтов на входе, один раз на неправильно закодированный входной файл.

2. Удаление предупреждения, и изменение кодировки по умолчанию на "ascii".

Если строка Unicode с декларацией кодирования будет передана в compile(), будет сгенерировано событие SyntaxError.

Читайте также: