Ошибки Python Unicode, синхронизируйте среду разработки и производство

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

Pınar Karsıyaka

в моей среде разработки (Aptana с PyDev на Mavericks Mac с последней установкой homebrew python) обработка этой строки не приводит к ошибке и выводится на консоль как

P\u0131nar Kars\u0131yaka v Torku Selcuk

но в производственной среде стандартные Ubuntu и Python устанавливаются на маленькую коробку Amazon EC2, это печатается как

P\xc4\xb1nar Kars\xc4\xb1yaka v Torku Selcuk

и выдает одну из ужасных ошибок Python,

UnicodeEncodeError: 'ascii' codec can't encode character u'\u0131' in position 50: ordinal not in range(128)

Я хотел бы знать, как (если возможно) сделать так, чтобы рабочая среда могла работать с этими персонажами, как моя среда разработки, но также хотела бы иметь возможность изменить мою среду разработки, чтобы она ломалась, как рабочая, поэтому что я могу обрабатывать случаи, когда это происходит в коде.

Спасибо за любую помощь в этом отношении.

Mac Python — Python 2.7.5 (по умолчанию, 1 ноября 2013 г., 18:38:34) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] на darwin

Ubuntu Python — Python 2.7.3 (по умолчанию, 10 апреля 2013 г., 06:20:15) [GCC 4.6.3] на linux2


person seaders    schedule 27.03.2014    source источник
comment
Питон 2 или Питон 3?   -  person metatoaster    schedule 28.03.2014
comment
Вероятно кодировка оболочки на сервере не UTF-8, а у вас дома. Сравните значение, скажем, echo $LC_ALL для каждого.   -  person Two-Bit Alchemist    schedule 28.03.2014
comment
Python 2.7 на каждом, добавил к вопросу полную информацию. @Two-BitAlchemist, у меня это отображается как пустое / пустое на обеих машинах.   -  person seaders    schedule 28.03.2014
comment
@seaders Хорошо, как насчет $LANG или $LC_CTYPE? Кроме того, вы запускаете программу Mac Terminal дома, но получаете доступ к своему блоку EC2 с помощью чего-то вроде ssh?   -  person Two-Bit Alchemist    schedule 28.03.2014
comment
@Two-BitAlchemist, $LC_TYPE снова пусто в обоих, $LANG — это en_IE.UTF-8 в dev, en_US.UTF-8 в коробке Amazon. На коробке EC2, да, sshing, локально, я запускаю команды, о которых вы спрашиваете, в iTerm, но весь остальной код Python в Aptana.   -  person seaders    schedule 28.03.2014
comment
@seaders Хорошо, вы настроены на UTF-8 на обоих. Может, в одном месте кодировка файла ASCII, а в другом UTF-8? В Python 2.7 вам не нужно устанавливать # -*- coding: utf-8 -*- в начале файла? IIRC, UTF-8 стал по умолчанию в Py3K. Вы сделали это с файлами, по крайней мере, на вашем ящике EC2? (Лучше, если это будет в обоих местах.)   -  person Two-Bit Alchemist    schedule 28.03.2014
comment
@Two-BitAlchemist, спасибо за всю эту помощь, но только что попробовал это в проблемном файле и точке входа в приложение, и все равно не повезло.   -  person seaders    schedule 28.03.2014
comment
Можете ли вы опубликовать полную трассировку исключения? Это поможет определить, какая операция вызывает ошибку UnicodeEncodeError.   -  person Blckknght    schedule 24.04.2014
comment
добавьте # coding: utf8 в первую строку и сообщите нам результат   -  person mortymacs    schedule 25.04.2014


Ответы (2)


Если вы немного погрузитесь в ветку 2.7 исходников Python, вы обнаружите, что кодировка строк Unicode по умолчанию, во-первых, установите какое-то принудительное значение (сейчас это "ascii", хотя до этого было "utf-8"), но это переопределяется модулем сайта при каждом запуске интерпретатора.

Чтобы проверить поведение на каждой платформе, запустите:

$ python -c 'import sys; print(sys.getdefaultencoding())'

Теперь, если вы хотите сделать их четными, это не очень просто, потому что функция setdefaultencoding удален в модуле сайта, так что вам придется перезагрузить модуль sys, чтобы получить его:

$ python -c 'import sys; reload(sys); sys.setdefaultencoding("utf-8"); print(sys.getdefaultencoding())'

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

person piroux    schedule 27.04.2014

Версии библиотеки

Пожалуйста, убедитесь, что все версии библиотек одинаковы, я подозреваю, что есть изменение API, которое возвращает unicode против str из какого-то внешнего источника данных. Я видел эти проблемы раньше при обновлении SQLObject и Cherrypy. Также важны настройки источника данных, например, если вы используете сервер mysql, вам нужно обратить внимание на default_encoding.

В ваших вопросах не указан источник данных, трудно догадаться.

По крайней мере, сделайте pip freeze в обеих средах и сравните номера версий.

Кодировка по умолчанию

Проверьте, есть ли sitecustomize.py в одной из сред - это официальный способ настроить любые шаткие вещи (чего вам в любом случае не следует делать, но это уже другая история).

Вероятно, он делает именно то, что предлагает @chocko01 - устанавливает кодировку по умолчанию. Проверьте это, зарегистрировав sys.getdefaultencoding() в обеих средах.

Установка кодировки по умолчанию в Python делает преобразование unicode<->str (Python2) и str<->bytes (Python3) прозрачным, но в долгосрочной перспективе это плохая идея. Помните, что explicit is better than implicit.

Отследите свои данные

сложно взломать CCC, но если вы не сможете отразить эту конкретную проблему в воспроизводимом тесте , второй лучший способ — сбросить тонны журналов, а затем вернуться назад и посмотреть, откуда исходит ваш странный ввод.

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

На момент ошибки это unicode в вашей локальной среде и UTF-8 закодировано, также известное как str в производственной среде. Тот факт, что у вас есть образец для обеих сред, говорит о том, что вы можете воспроизвести проблему. Возможно, вам также следует написать автоматический тест.

person Dima Tisnek    schedule 28.04.2014
comment
это не ответ, а вместо этого должен быть комментарий к stackoverflow.com/a/23319208/247648 - person Giel; 30.04.2014
comment
расширенный; Кстати, @Giel, если мы собираемся быть педантичными, ваша ссылка указывает на мой ответ, а не на вопрос. - person Dima Tisnek; 30.04.2014
comment
нет, это указывает на ответ choko01, и я вижу, что вы полностью переписали свой ответ, поэтому я не буду отрицать это - person Giel; 30.04.2014
comment
ааа, извините, это проблема очень большого дисплея - привязки html трудно интерпретировать :) - person Dima Tisnek; 30.04.2014