Печать Python работает по-разному на разных серверах - PullRequest
6 голосов
/ 18 сентября 2010

Когда я пытаюсь напечатать строку Unicode на моем сервере dev, он работает правильно, но рабочий сервер вызывает исключение.

File "/home/user/twistedapp/server.py", line 97, in stringReceived
    print "sent:" + json
File "/usr/lib/python2.6/dist-packages/twisted/python/log.py", line 555, in write
    d = (self.buf + data).split('\n')
exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 28: ordinal not in range(128)

На самом деле это скрученное приложение и печать вперед в файл журнала.

repr () строк одинаковы. Локаль установлена ​​на en_US.UTF-8.

Есть ли какие-либо конфигурации, которые мне нужно проверить, чтобы они работали одинаково на обоих серверах?

Ответы [ 2 ]

7 голосов
/ 18 сентября 2010

print Строка Unicode зависит от sys.stdout (стандартный вывод процесса), имеющего правильный атрибут .encoding, который Python может использовать для кодирования строки Unicode в строку байтов для выполнения требуемой печати - и это настройка зависит от того, как настроена ОС, куда направляется стандартный вывод и т. д.

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

Вы можете проверить getattr(sys.stdout, 'encoding', None), чтобы увидеть, есть ли кодировка (если она есть, вы можете просто держать пальцы скрещенными, чтобы она была правильной ... или, возможно, попробовать какую-то хитрость для конкретной платформы, чтобы угадать правильную Системная кодировка для проверки ;-). Если это не так, в общем, нет надежного или кроссплатформенного способа угадать, что это может быть. Вы можете попробовать 'utf8', универсальную кодировку, которая работает во многих случаях (конечно, больше, чем ascii ;-), но это действительно вращение колеса рулетки.

Для большей надежности ваша программа должна иметь свой собственный файл конфигурации, чтобы сообщить ей, какую выходную кодировку использовать (возможно, с 'utf8' в качестве значения по умолчанию, если не указано иное).

Для переносимости также лучше выполнять собственное кодирование, то есть не

print someunicode

а точнее

print someunicode.encode(thecodec)

и на самом деле, если вы предпочитаете не полный вывод, а сбой,

print someunicode.encode(thecodec, 'ignore')

(который просто пропускает не кодируемые символы) или, как правило, лучше

print someunicode.encode(thecodec, 'replace')

(который использует заполнители с вопросительным знаком для некодируемых символов).

1 голос
/ 18 сентября 2010

Unicode не поддерживается встроенными наблюдателями журнала Twisted. См. http://twistedmatrix.com/trac/ticket/989, чтобы узнать, как добавить поддержку, или узнать, что вы можете сделать, чтобы помочь.

До тех пор, пока # 989 не будет решена, и исправление находится в версии Twisted, на которой развернуто ваше приложение, не регистрируйте юникод. Только лог str.

...