Comments 53
Годная, полезная статья.
Я бы еще раскрыл тему как читать/писать юникодные файлы: codecs.open вместо file() и про PEP 0263.
Я бы еще раскрыл тему как читать/писать юникодные файлы: codecs.open вместо file() и про PEP 0263.
по поводу файлов
#! /usr/bin/env python
# -*- coding: utf-8 -*-
операции с файлами становятся уникодными=)
ну еще со строками магия проходит вроде
регулярки работают
m=re.match('^(第)([0-9]+)(届|期)',s)
Как практика показывает, входные данные лучше отгонять в UTF-8
тогда проблемы вроде того что одни и теже данные python, c++ и так далее не сильно актуальные…
Отдельно надо выделить если происходят операции за Базой данных тут кодировки тоже важно…
З.Ы каждый программист должен начинать новый язык с UTF-8 / Unicode :) решать вопрос чтобы устойчивая программа была к любым символам
#! /usr/bin/env python
# -*- coding: utf-8 -*-
операции с файлами становятся уникодными=)
ну еще со строками магия проходит вроде
регулярки работают
m=re.match('^(第)([0-9]+)(届|期)',s)
Как практика показывает, входные данные лучше отгонять в UTF-8
тогда проблемы вроде того что одни и теже данные python, c++ и так далее не сильно актуальные…
Отдельно надо выделить если происходят операции за Базой данных тут кодировки тоже важно…
З.Ы каждый программист должен начинать новый язык с UTF-8 / Unicode :) решать вопрос чтобы устойчивая программа была к любым символам
Не операции становятся уникодными, а исходный текст скрипта :).
Файлы [данных] все же придется читать и декодировать руками.
> входные данные лучше отгонять в UTF-8
Ни в коем случае! UTF-8 — это внешнее представление. Входные данные надо отгонять в юникод, со всеми строками работать только в юникоде, а сохранять снова в UTF-8. Кстати, в C++ c UTF-8 вообще можно повеситься (ну или забыть работу со строками).
Файлы [данных] все же придется читать и декодировать руками.
> входные данные лучше отгонять в UTF-8
Ни в коем случае! UTF-8 — это внешнее представление. Входные данные надо отгонять в юникод, со всеми строками работать только в юникоде, а сохранять снова в UTF-8. Кстати, в C++ c UTF-8 вообще можно повеситься (ну или забыть работу со строками).
Насчет входных файлов соглашусь…
У меня просто все данные в UTF-8, входные из файлов поэтому работает 2.6/2.7
Внешение представление в UTF-8 спасает…
UTF-8 для символов a-z 1byte если идет кирилица А_Я и так далее 2 byte.
С точки зрения C/C++ когда strlen(ansi) = 10 с точки зрения strlen(utf-8) 10 длина не понятна(может символы 1 +2 +2 +2 +1+1 ).
Если код не ориентирован на чёткий поиск, а склейка строк то strcpy/strcat можно пользовать…
з.ы. пора тему Unicode / UTF-8/ UTF-16 как курс или пособие, обобщение для разных языков…
У меня просто все данные в UTF-8, входные из файлов поэтому работает 2.6/2.7
Внешение представление в UTF-8 спасает…
UTF-8 для символов a-z 1byte если идет кирилица А_Я и так далее 2 byte.
С точки зрения C/C++ когда strlen(ansi) = 10 с точки зрения strlen(utf-8) 10 длина не понятна(может символы 1 +2 +2 +2 +1+1 ).
Если код не ориентирован на чёткий поиск, а склейка строк то strcpy/strcat можно пользовать…
з.ы. пора тему Unicode / UTF-8/ UTF-16 как курс или пособие, обобщение для разных языков…
Чё за бред? Хабр — УГ.
Толсто.
Терпите. Скоро вас запикает НЛО.
Что полезного сделали вы для хабрсообщества, чтоб его критиковать?
Хабрасэппуку?
Это вы зря. Мне недавно пришла идея автоматического пополнения словаря с использованием нейронной сети. Идея не нова, просто самообучался. Столкнулся с проблемой кодировки, перерыл полинтернета. Нашел ответы на вопросы, но все очень разрозненно, плюс умные люди помогли, теория все равно осталась мне не понятна. А это фактически единственная статья в рунете, которая все раскладывает по полочкам.
Не знаю, столкнулся с юникодом в джанге, нашел решение за 5 минут. А в статье дикая мешанина из того, что такое юникод и работа с кодировками отличными от ascii в питоне.
ru.wikipedia.org/wiki/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4
кстати, по работе с кодировками по ссылке есть все в одном месте (например в self.статье про ignore, replace всего одна строчка, а в доках масса примеров и даже BOM упомянут :)):
docs.python.org/howto/unicode.html
ru.wikipedia.org/wiki/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4
кстати, по работе с кодировками по ссылке есть все в одном месте (например в self.статье про ignore, replace всего одна строчка, а в доках масса примеров и даже BOM упомянут :)):
docs.python.org/howto/unicode.html
У Юрия Юревича есть подробная презентация на эту тему:
video.google.com/videoplay?docid=5035388502434680056
video.yandex.ru/external/4611686019030667986/view/7317091/?cauthor=anarresti&cid=1
www.rupy.ru/static/files/07/02/12/rupyru2007-yurevich-unicode.pdf
video.google.com/videoplay?docid=5035388502434680056
video.yandex.ru/external/4611686019030667986/view/7317091/?cauthor=anarresti&cid=1
www.rupy.ru/static/files/07/02/12/rupyru2007-yurevich-unicode.pdf
Непонятно, чем «символы» отличаются от байтов. В конечном счете они все равно хранятся как любая другая информация в памяти — как байты. Поясните разницу.
Символ — это, например, «CYRILLIC SMALL LETTER A», а байт — это нолики и еденицы, например '\xe0'. Для того, что б байт стал символом, необходима кодировка. И в зависимоти от кодировки, этот байт (или байты) может представлять разные символы.
Определение одного символа не обязательно умещается в один байт.
Я и сказал «чем символы отличаются от байтов?» а не «чем символ отличается от байта?».
Я понимаю, что символ может быть больше байта, я не понимаю вот это «не обязательно».
То есть в юникоде разные символы имеют разный размер? Вообще что можно почитать по этому поводу. поменьше и попроще, чем стандарт?
Я понимаю, что символ может быть больше байта, я не понимаю вот это «не обязательно».
То есть в юникоде разные символы имеют разный размер? Вообще что можно почитать по этому поводу. поменьше и попроще, чем стандарт?
Один символ может занимать несколько байт.
Похоже что косяки машинного перевода немного накладывает отпечаток…
...«Хорошо, я понял чем есть строка.»…
А так по логике вещей показалось странным, что:
байты в Unicode — это кодирование
а Unicode в батый — это де-кодирование
интуитивно хочется наоборот… хотя смысл, понятен, и зависит от того что-во-что кодировать и следовательно де-кодировать
...«Хорошо, я понял чем есть строка.»…
А так по логике вещей показалось странным, что:
байты в Unicode — это кодирование
а Unicode в батый — это де-кодирование
интуитивно хочется наоборот… хотя смысл, понятен, и зависит от того что-во-что кодировать и следовательно де-кодировать
А мне именно такая логика кажется естественной.
У символа есть «код», мы получаем код из символа декодированием оного.
У символа есть «код», мы получаем код из символа декодированием оного.
Нет, это просто стиль такой выбран. А вобще автор совсем не русско-говорящий :)
>> интуитивно хочется наоборот
дык на самом деле и есть наоборот — байты в Unicode — это декодирование.
>> интуитивно хочется наоборот
дык на самом деле и есть наоборот — байты в Unicode — это декодирование.
"string".decode('ascii') # декодируем в юникод
u"string".encode('ascii') # переводим юникод в кодировку ascii
Все как раз наоборот
>>
На сколько я понимаю, UTF-16 может кодировать максимум 65 535 символов. Возможно, вы ошиблись?
На данный момент в Юникод-стандарте есть немного более 100 тысяч символов, тогда как UTF-16 позволяет поддерживать более одного миллиона (UTF-8 — и того больше).
На сколько я понимаю, UTF-16 может кодировать максимум 65 535 символов. Возможно, вы ошиблись?
Тогда UTF-8 кодирует 255 символов?
Нет. «16» в UTF-16 означает размер используемого слова: каждый code point в UTF-16 кодируется одним или более 16-битными словами.
Нет. «16» в UTF-16 означает размер используемого слова: каждый code point в UTF-16 кодируется одним или более 16-битными словами.
16 в названии совсем не значит, что используются 16 бит\2 байта\65 535 доступных комбинаций. Деталей кодировки не знаю, число взял сами знаете откуда. Посмотреть детали думаю можно там же (пока не закрыли в знак протеста против SOPA:) )
Согласно Вики и в UTF-8 и в UTF-16 равное число возможных символов — 1,112,064
Совершенно верно. Но можно расширить по аналогии правила построения UTF-8 на более длинные последовательности и получить так называемые overlong sequences. Хотя в стандарте прямо написано, что они ошибочны, к сожалению некоторые «хакеры» считают, что они выше стандарта и говорят, что в UTF-8 больше кодов, чем написано в стандарте, да ещё и реализуют их поддержку в своих программах (например, в eglibc bugs.debian.org/cgi-bin/bugreport.cgi?bug=555922 ).
И да, не называйте юникодные code points символами. Не каждый code point можно нарисовать в виде символа и даже есть такие code points, которые называются noncharacters. См. также en.wikipedia.org/wiki/Mapping_of_Unicode_characters
И да, не называйте юникодные code points символами. Не каждый code point можно нарисовать в виде символа и даже есть такие code points, которые называются noncharacters. См. также en.wikipedia.org/wiki/Mapping_of_Unicode_characters
ммм… Code point. Пасиб, проще с такой терминологией работать.
Какой-то русский аналог у этого названия есть?
Какой-то русский аналог у этого названия есть?
прочитал ссылку на баг в eglibc. мдааа…
Ещё один кейс на проверку в программах (я тестировщик). Правда не очень понятно кого винить потом проблеме — своих разработчиков, или разработчиков билиотеки которую они использовали.
Особенно «порадовал» комментарий — «Nobody has ever shown any evidence why this is a bad idea.»
Стандарты видимо люди тоже просто так придумывали…
Ещё один кейс на проверку в программах (я тестировщик). Правда не очень понятно кого винить потом проблеме — своих разработчиков, или разработчиков билиотеки которую они использовали.
Особенно «порадовал» комментарий — «Nobody has ever shown any evidence why this is a bad idea.»
Стандарты видимо люди тоже просто так придумывали…
> в тоже время в кодировке ISO-8859-1 это греческая "ß".
В ISO-8859-1 нет греческих букв. Это немецкая Eszett. (на правах занудства)
В ISO-8859-1 нет греческих букв. Это немецкая Eszett. (на правах занудства)
Спасибо за занудство:)
Хорошая статья, советую еще раскрыть тему локалей, без этого материал неполный.
Жаль что не смотря на теорию проблема кодировок это сверхбольное место питона, которое каждый раз съедает у меня массу сил и времени. Заткнулся какой ни будь встроенный модуль для работы с gzip на русскоязычных именах файлах и рабочий день коту под хвост.
В python 3000 демонстрировать особо нечего, для самого питона проблема решена на корню как в java, все строки — юникод, на практике ад с портированием библиотек и, имхо, эта ветка сдохнет и на ее место доэволюционирует 2.x, х/з как при этом решится проблема со строками.
Жаль что не смотря на теорию проблема кодировок это сверхбольное место питона, которое каждый раз съедает у меня массу сил и времени. Заткнулся какой ни будь встроенный модуль для работы с gzip на русскоязычных именах файлах и рабочий день коту под хвост.
В python 3000 демонстрировать особо нечего, для самого питона проблема решена на корню как в java, все строки — юникод, на практике ад с портированием библиотек и, имхо, эта ветка сдохнет и на ее место доэволюционирует 2.x, х/з как при этом решится проблема со строками.
Мне очень понравилась тема Unicode в Dive into Python 3
diveintopython3.ep.io/strings.html
diveintopython3.ep.io/strings.html
Честно говоря, до этой статьи я понимал что такое кодировки и как с ними работать.
Очень тяжелая статья для новичков, которая лишь внесет кашу в головы.
Очень тяжелая статья для новичков, которая лишь внесет кашу в головы.
Увидел сначала сколько букв — испугался.
Когда осилил, понял, что не так уж и много. Читается нормально.
Полезная статья!
Когда осилил, понял, что не так уж и много. Читается нормально.
Полезная статья!
Нужная статья, основная полезность направление decode / encode.
Некоторая мнемоника:
1. Для себя сделал ассоциации типа decode более тяжелое по звучанию соответственно создает тяжелый utf,
encode легкое создает легковесный байт.
2. Байты это непонятный код, который чтобы увидеть надо декодировать в символы (utf), а чтобы символы превратить в код (т.е. байты), их соответственно нужно закодировать (encode).
Некоторая мнемоника:
1. Для себя сделал ассоциации типа decode более тяжелое по звучанию соответственно создает тяжелый utf,
encode легкое создает легковесный байт.
2. Байты это непонятный код, который чтобы увидеть надо декодировать в символы (utf), а чтобы символы превратить в код (т.е. байты), их соответственно нужно закодировать (encode).
На виндах у петона вечные проблемы с юникодом, что у третьего, что у второго. На линуксе с этим проще.
Да и не только с юникодом.
Да, я по это причине все пытаюсь переползти на макось но пока не складывается.
Да, я по это причине все пытаюсь переползти на макось но пока не складывается.
А чем проблемность юникода в Windows вызвана?
не волнуйтесь, в линуксе тоже есть вечные проблемы с вводом/выводом изнутри библиотек.
например, stderr направленный в файл — работает, а на консоль — падает, а на appengine — генерит servererror.
например, stderr направленный в файл — работает, а на консоль — падает, а на appengine — генерит servererror.
Правильно ли я понимаю, что если везде и всюду в константах и на входе программы будет только юникод (вместо байтстрок) — это избавит от проблем вида «UnicodeDecodeError» в крайне неожиданных местах?
(например, от лютых кабздецов, когда appengine-приложение падает в «server error» из-за того, что логгер не может нарисовать лог.)
(например, от лютых кабздецов, когда appengine-приложение падает в «server error» из-за того, что логгер не может нарисовать лог.)
А в каком формате сам python внутри хранит строки в 2.х и 3.х?
Забавно, вот что по ссылке на перевод статьи Спольски :)
картинка для предыдущего комментария img.skitch.com/20120320-mb9qxs4tukfin98ria2wb7rjt3.png
Меня спасает
Таким образом весь текст становится unicode, если не укажете что он b'текст'
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
Таким образом весь текст становится unicode, если не укажете что он b'текст'
Sign up to leave a comment.
Юникод для чайников