При передаче вывода программы Python интерпретатор Python запутывается в кодировании и устанавливает для него значение None. Это означает такую программу:
# -*- coding: utf-8 -*-
print u"åäö"
будет нормально работать при нормальной работе, но не с:
UnicodeEncodeError: кодек 'ascii' не может кодировать символ u '\ xa0' в позиции 0: порядковый номер не в диапазоне (128)
при использовании в последовательности труб.
Каков наилучший способ сделать эту работу при обвязке? Могу ли я просто сказать ему использовать любую кодировку оболочки / файловой системы / что бы она ни использовала?
Советы, которые я видел до сих пор, это изменить ваш site.py напрямую или жестко закодировать код по умолчанию с помощью этого хака:
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
print u"åäö"
Есть ли лучший способ заставить трубопровод работать?
chcp 65001
перед выполнением сценария. Это может иметь проблемы, но это часто помогает, и не требует большого набора текста (меньше, чемset PYTHONIOENCODING=utf_8
).setx PYTHONENCODING utf-8
сделать его постоянным, если вы хотите сохранить набор текста.Ответы:
Ваш код работает при запуске в скрипте, потому что Python кодирует выходные данные в любую кодировку, используемую вашим терминальным приложением. Если вы используете трубопровод, вы должны закодировать его самостоятельно.
Практическое правило: всегда используйте Unicode для внутреннего использования. Расшифруйте то, что вы получаете, и закодируйте то, что вы отправляете.
Другим дидактическим примером является программа на Python, которая конвертирует между ISO-8859-1 и UTF-8, делая все в верхнем регистре между ними.
Установка системной кодировки по умолчанию - плохая идея, потому что некоторые модули и библиотеки, которые вы используете, могут полагаться на факт, что это ASCII. Не делай этого.
источник
sys.stdout
кажется более приятным способом.PYTHONIOENCODING
если вы перенаправляете стандартный вывод скрипта в Python 2.Во-первых, относительно этого решения:
Непрактично каждый раз явно печатать с заданной кодировкой. Это было бы повторяющимся и подверженным ошибкам.
Лучшее решение - изменить
sys.stdout
в начале вашей программы кодирование с выбранной кодировкой. Вот одно решение, которое я нашел на Python: Как выбрать sys.stdout.encoding? , в частности комментарий от "Тока":источник
def myprint(unicodeobj): print unicodeobj.encode('utf-8')
- вы автоматически обнаруживаете кодирование терминала, проверяяsys.stdout.encoding
, но вы должны учитывать тот случай, когда он естьNone
(т.е. при перенаправлении вывода в файл) так что вам нужна отдельная функция в любом случае.Вы можете попробовать изменить переменную среды "PYTHONIOENCODING" на "utf_8". Я написал страницу в моем испытании с этой проблемой .
Tl; dr поста в блоге:
дает тебе
источник
sys.stdout = codecs.getwriter(encoding)(sys.stdout)
. Это может быть сделано из программы Python, поэтому пользователь не обязан устанавливать переменную env.PYTHONIOENCODING
работает. То, как байты интерпретируются как текст, определяется пользовательской средой. Ваш сценарий не должен предполагать и определять пользовательскую среду, какую кодировку символов использовать. Если Python не выбирает настройки автоматически, этоPYTHONIOENCODING
можно сделать для вашего скрипта. Вам это не нужно, если вывод не перенаправлен в файл / канал.сделать работу, но не могу установить ее на самом Python ...
то, что мы можем сделать, это проверить, если не установлен, и сказать пользователю установить его перед вызовом скрипта с помощью:
Обновление, чтобы ответить на комментарий: проблема просто существует при передаче на стандартный вывод. Я тестировал в Fedora 25 Python 2.7.13
кот б.пи
работает ./b.py
работает ./b.py | Меньше
источник
sys.stdout.encoding
автоматически устанавливается на основеLC_CTYPE
значения локали.У меня была похожая проблема на прошлой неделе . Это было легко исправить в моей IDE (PyCharm).
Вот мое исправление:
Начиная с строки меню PyCharm: Файл -> Настройки ... -> Редактор -> Кодировки файлов, затем установите: «Кодировка IDE», «Кодировка проекта» и «Кодировка по умолчанию для файлов свойств» ВСЕ в UTF-8, и теперь она работает Как колдовство.
Надеюсь это поможет!
источник
Спорная санированная версия ответа Крейга МакКуина.
Использование:
источник
Я мог бы "автоматизировать" это с помощью вызова:
Да, здесь можно получить бесконечный цикл, если этот "setenv" не работает.
источник
Я просто подумал, что упомяну здесь кое-что, с чем мне пришлось долго экспериментировать, прежде чем я наконец понял, что происходит. Это может быть настолько очевидным для всех здесь, что они не потрудились упомянуть об этом. Но это помогло бы мне, если бы они имели, так по этому принципу ...!
NB: я использую Jython специально, v 2.7, так что, возможно, это не относится к CPython ...
NB2: первые две строки моего файла .py здесь:
Механизм построения строки "%" (AKA "оператор интерполяции") также вызывает ДОПОЛНИТЕЛЬНЫЕ проблемы ... Если кодировка "среды" по умолчанию - ASCII, и вы пытаетесь сделать что-то вроде
У вас не будет проблем с запуском в Eclipse ... В CLI Windows (окно DOS) вы обнаружите, что кодировка - это кодовая страница 850 (моя ОС Windows 7) или что-то подобное, которая может обрабатывать европейские символы с акцентом по крайней мере, поэтому буду работать
тоже будет работать.
Если, OTOH, вы перенаправляете файл из CLI, кодировкой stdout будет None, которая по умолчанию будет ASCII (в любом случае, в моей ОС), которая не сможет обрабатывать ни один из вышеперечисленных отпечатков ... (страшная кодировка ошибка).
Итак, вы можете подумать о перенаправлении стандартного вывода с помощью
и попробуйте запустить в CLI трубопровод к файлу ... Как ни странно, печать A выше будет работать ... Но печать B выше вызовет ошибку кодирования! Следующее, однако, будет работать нормально:
Вывод, к которому я пришел (условно), заключается в том, что если строка, указанная как строка Unicode с префиксом «u», передается механизму% -обработки, то она, по-видимому, предполагает использование кодировки среды по умолчанию, независимо от установили ли вы stdout для перенаправления!
Как люди справляются с этим - вопрос выбора. Я хотел бы, чтобы эксперт по Unicode рассказал, почему это происходит, правильно ли я понял это, каким образом это предпочтительное решение, применимо ли это также к CPython , происходит ли это в Python 3 и т. Д., И т. Д., И т. Д.
источник
"fréd"
это последовательность байтов, а не строка в Юникоде, поэтомуcodecs.getwriter
обертка оставит ее в покое. Вам нужен ведущийu
, илиfrom __future__ import unicode_literals
.Я столкнулся с этой проблемой в унаследованном приложении, и было трудно определить, где что было напечатано. Я помог себе с этим взломать:
Поверх моего скрипта test.py:
Обратите внимание, что это изменяет ВСЕ вызовы на печать для использования кодировки, поэтому ваша консоль напечатает это:
источник
В Windows эта проблема возникала очень часто при запуске кода Python из редактора (например, Sublime Text), но не при запуске из командной строки.
В этом случае проверьте параметры вашего редактора. В случае SublimeText это
Python.sublime-build
решило это:источник