Юникод в Python 2.x — что это и зачем?
В реальном мире строковыми данными обмениваются в какой-то кодировке. Например, koi8-r, cp1251, utf-8. И когда тебе приходят данные, ты во многих случаях знаешь, какая это кодировка. Но когда тебе приезжают данные из разных мест в разных кодировках, работать с ними одновременно довольно напряжно — надо всегда об этом помнить.
Чтоб облегчить жизнь, внутри программ используют юникодные данные — это которые
u'test'. Их можно получить декодированием обычной строки, типа
'test'.decode('utf-8'), и точно так же кодированием превратить в обычную
строку: u'test'.encode('utf-8').
Юникод — это способ представления, а не хранения данных. Т.е. юникод — это стандарт, который сопоставляет символу какое-то число — те самые \u<номер>. А кодировка — это способ хранения этого числа, например UTF-81 хранит числа таким образом, что символы латиницы (символы с номером меньше 128) кодируются в один байт, и таким образом соответствует ASCII. При этом у кириллицы — двухбайтные символы.
Работа происходит так: ты получаешь какие-то данные от своего окружения, декодируешь их в юникод, работаешь, а когда отдаëшь наружу, опять превращаешь в строку. Наружу — это не только вывод на экран, это и запись в файлы, и в базу данных. Хотя драйверы БД (а тем более ORM) обычно сами преобразуют юникод в нужную кодировку.
Цель этой заметки — всего лишь дать базовое понятие о том, почему в питоне есть отдельный тип для юникодных данных, а для более полного понимания можно почитать разное:
- The Absolute Minimum … About Unicode … — классика от Джоэля
- Repeat after me: Unicode is not UTF-\d{1,2} — много текста про то, что Unicode и UTF-xx — разные вещи
- русскую википедию
- английскую википедию
-
Unicode Transformation Format ↩

Comments: 11 Subscribe (already: 5) Comment post
Слабовато. Новички это узнают в первый же день изучения Python. Стоило бы еще упомянуть, что в Python 3.x уже нет обычных строк, а вемь текст юникодный.
Если б они это узнавали, никто б таких вопросов, как задают, не задавал бы.
Это после понимания кажется, что всё прозрачно и понятно, а до народ оооочень часто ругается на маловменяемые UnicodeEncodeError/ UnicodeDecodeError в дебрях чужого кода, часто путают encode/decode (усуглубляется тем, что оба метода есть и у str и у unicode), удивляются, почему print unicode_data это плохо, etc… Так что вводный пост, на который можно ссылаться в дальнейшем — это очень хорошо.
Я вот часто ссылаюсь на http://www.rupy.ru/member/5/#paper-6 $)
P.S.Хотя да, несколько запоздало, пора уже писать “Юникод в Py 3.1” :)
Кому пора, а кому и 2.х еще вполне актуален. ;)
Кстати, я смотрел юникод в Py 3.0 пока в отпуске был. Много вопросов к нему. Особенно что касается неявных перекодировок данных “из внешнего мира” (os.environ, os.path). Надо будет Py 3.1 по этому поводу пощупать…
А ещё бывает такая стиуация когда кодируется в неправильную кодировку, потом перекодируется ещё в какую нибудь и вообще я даже ситуацию не могу толком описать, не то что методы решения.. В общем это я про русские мп3 тэги как вы наверное догадались..
просто в ID3v1 используются однобайтовые строки, а многие проигрыватели музыки до сих пор позволяют писать данные в ID3v1. Вот в ID3v2 уже есть понятие кодировка, и многие проигрыватели им даже умеют как-то пользоваться.
Скажи вот у меня такой случай:
In [14]: resp.content
Out[14]: ‘\r\n\r\n\r\n\r\n\r\n<html xmlns=”http://www.w3.org/1999/xhtml”>\r\n <head>\r\n <meta http-equiv=”content-type” content=”text/html; charset=utf-8” />\r\n \r\n \n<title>Japanese innovation | \xd0\xaf\xd0\xbf\xd0\xbe\xd0\xbd\xd0\xb8\xd1\x8f \xd0\xb8\xd0\xbd\xd0\xbd\xd0\xbe\xd0\xb2\xd0\xb0\xd1\x86\xd0\xb8\xd0\xb8</title>\n\r\n
Что это за формат, и как его можно преворатить во что то читаемое (ну или такое где можно найти строку текста)
Самый обычный utf-8.
resp.content.decode(‘utf-8’) если нужно найти строчку текста в title, можешь взять скажем beautifulsoup, elementtree или html5lib, или просто написать regexp. для этого перекодировать вообще не надо ничего — все сами разберутся с кодировкой (впрочем, не уверен насчёт elementtree, ну и regexp ничего не раскодирует, ессно).
В том то и дело что когда мне нужно вытянуть например значение alt атрибута в каком нибудь из img, то например запрос
хотя если написать: print response то текст (весь код страницы) будет читабельным. Как то можно с этим справиться?
Comment form for «Юникод в Python 2.x - что это и зачем?»