Подтвердить что ты не робот

Кодировка Stdout в python

Есть ли веская причина, почему я не должен запускать все мои программы python с этим? Есть ли что-то особенное, потерянное при выполнении exec вроде этого?

#!/usr/bin/python
import os, sys
if sys.stdout.encoding == None:
    os.putenv("PYTHONIOENCODING",'UTF-8')
    os.execv(sys.executable,['python']+sys.argv)
print sys.stdout.encoding

Есть 60 вопросов о PYTHONIOENCODING, поэтому я предполагаю, что это общая проблема, но если вы этого не знаете, это делается, потому что, когда sys.stdout.encoding == None, тогда вы могут печатать только символы ascii, поэтому, например, print "åäö" выдаст исключение..

EDIT Это происходит со мной, когда stdout - это труба; python encoding.py|cat установит кодировку в None

Другим решением является изменение кодека stdout sys.stdout = codecs.getwriter('utf8')(sys.stdout), который, как я предполагаю, является правильным ответом, рассылает комментарии по этому вопросу.

4b9b3361

Ответ 1

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

Прежде всего:

sys.stdout.encoding - None, если Python не знает, какая кодировка поддерживает stdout. Это, в большинстве случаев, связано с тем, что он вообще не поддерживает какую-либо кодировку. В вашем случае это потому, что stdout - это файл, а не терминал. Но он может быть установлен в None, поскольку Python также не может обнаружить кодировку терминала.

Во-вторых: вы задаете переменную окружения, а затем снова запускаете новый процесс с помощью команды smae. Это довольно уродливо.

Итак, если вы не планируете быть единственным, кто использует ваши программы, вы не должны запускать их так. Но если вы планируете использовать только свою программу, то продолжайте.

Более подробное объяснение

Лучшим общим решением под Python 2 является обработка stdout как то, что это такое: 8-битный интерфейс. И это означает, что все, что вы печатаете на stdout, должно быть 8 бит. Вы получаете сообщение об ошибке при попытке печати данных Юникода, потому что затем печать будет пытаться кодировать данные Unicode для кодирования stdout, а если это None, то он будет считать ASCII и сбой, если вы не установите PYTHONIOENCODING.

Но при печати закодированных данных у вас нет этой проблемы. Следующее работает отлично, даже когда выход передается по трубопроводу:

print u'ÅÄÖ'.encode('UTF8')

(Однако это не сработает под Python 3, потому что в Python 3, stdout больше не является 8-битным IO, вы должны указывать данные Unicode, и он будет кодироваться сам по себе.Если вы дадите ему двоичные данные, он напечатает представление, поэтому на Python 3 у вас нет этой проблемы в первую очередь).