Personal tools
You are here: Home Статьи FAQ & HOWTO Что делать , если в Zope проблемы с кодировкой?
Document Actions

Что делать , если в Zope проблемы с кодировкой?

by cray last modified 2007-03-07 06:28

Наверно, многие из вас видели это: "UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 0: ordinal not in range(128)". Почему это происходит? Потому что кто-то в очередной раз программируя str() или unicode() забыл о простой истине: что бы преобразовать одно в другое нужно два параметра: строка и кодировка. Причем кодировка должна соответствовать тому, что есть в строке и должна откуда-то браться.

Несколько раз натыкаясь на эту ошибку мы пытались ее исправить, и ценой неимоверных усилий вытаскивали откуда-то правильную кодировку и исправляли ошибку. Откуда-то - это из запроса Request, из mime_type файла и других не менее трудно доступных мест. Во многих случаях, просто преобразование было не обоснованным и его удаление решало проблему.

Но т.к. программисты Zope по непонятной мне причине любят совать преобразование строки в уникод и обратно куда ни попадя (видимо, забыв что их сервер, по идее идеологов Zope, должен работать в UNICODE), то в конце-концов пришлось порекомендовать некий обходной путь решения таких проблем.

Как вы понимаете, у необязательного параметра "кодировка", в преобразованиях уникода, есть значение по умолчанию. Оно обычно равно ascii, но его можно поменять, отредактировав файл /usr/lib/python2.4/site.py (проконсультируйтесь с вашим местным знатоком по поводу того, где лежит этот файл у вас) и проставив там желаемую кодировку.

Нужное вам место выглядит вот так:

def setencoding():
   """Set the string encoding used by the Unicode implementation.  The
   default is 'ascii', but if you're willing to experiment, you can
   change this."""
   encoding = "ascii" # Default value set by _PyUnicode_Init()
   if 0:
       # Enable to support locale aware default string encodings.
       import locale
       loc = locale.getdefaultlocale()
       if loc[1]:
           encoding = loc[1]
   if 0:
       # Enable to switch off string to Unicode coercion and implicit
       # Unicode to string conversion.
       encoding = "undefined"
   if encoding != "ascii":
       # On Non-Unicode builds this will raise an AttributeError...
       sys.setdefaultencoding(encoding) # Needs Python Unicode build !

Я обычно ставлю 1 в первом операторе if, но у меня настроена локаль :), если у вы не знаете что это такое - то вам лучше удавиться в туалете или сделать явное присваивание, как первый шаг в сторону удавки :).

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

К сожалению, на сегодняшний день я не вижу других вариантов: волна ошибок слишком высока, что бы преодолеть ее одиночными усилиями.

Собственно, выводов для вас два:

  1. Если вам завтра сдавать ПО заказчику - отредактируйте site.py;
  2. Никогда без явной небходимости не указывайте преобразование строки в уникод и обратно: критерий явной необходимости простой: вы знаете что указать в качестве кодировки. Во всех остальных случаях нужно разбираться, почему вы в качестве параметра получаете то строку, то уникод и т.п....

Гм... В период разработки и тестирования, лучше site.py не править: хотя бы будете знать где кто закопан...


Powered by Plone CMS, the Open Source Content Management System