Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2013-01-28

UnicodeDecodeError

Типичная для нерусских нелатинских питонистов история. Все, кому для текстов недостаточно ASCII таблицы, наступают на грабли типа
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
Почему так, с чем это связано, какова механика и, главное, что с этим делать?
Покровы срывает Mikhail Korobov:

__str__ and __repr__ must return byte strings under Python 2.x, but it is not clear what encoding should they use. It is possible to have all the default encodings different on the same machine at the same time.
...
It is tempting to encode the values of __str__ and __repr__ to sys.stdout.encoding, and maybe set system default encoding to sys.stdout.encoding. This way REPL and print would work as expected and the result would be readable when it is possible.
...
The second option is to make __str__ and __repr__ return 7bit ASCII, using escaping and/or transliteration.
...
The third option is to always encode __str__ and __repr__ results to UTF-8.
...
All the tricks above are only necessary for Python 2.x because Python 3.x fixed the main issue: __repr__ and __str__ must return unicode in Python 3.x. Developers shouldn't worry about sys.stdout.encoding and many other things under Python 3.x because when the expected encoding is known, unicode would be encoded using this encoding.
Error handling become stricter; issues like 2.x %r issue are also not possible under Python 3.x.
I think that the best way is to write code with Python 3.x semantics (__str__ and __repr__ should return unicode) and have a decorator for fixing them for Python 2.x; this idea is from a thread at django-developers. Decorator then may be removed in a (far?) future alongside with dropping Python 2.x support.


Мой вариант — все переводить в UTF-8. Но, по любому, вариант с декоратором следует иметь в виду.

original post http://vasnake.blogspot.com/2013/01/unicodedecodeerror.html

2 комментария:

  1. Эх, это, пожалуй, одна из самых неприятных особенностей Питона 2.x. Только ради юникодных строк хочется перейти на Python 3.x, однако не все нужные библиотеки его еще поддерживают, хотя уже сколько лет прошло...

    ОтветитьУдалить
    Ответы
    1. Да, штука неприятная, особенно в начале карьеры питониста. Но потом нарабатывается некий рефлекс - всегда помнить о превращении юникодной строки в байтстринг, при печати особенно.
      Что поделать, нет в жизне щастя :)

      Удалить

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) Java (22) humor (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Manager (15) web-browser (15) Никонов (15) Klaipeda (14) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) Photo (9) купи/продай (9) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) serialization (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)