LINUX.ORG.RU

Решение для вывода кириллицы print-ом в cgi-скрипты на питоне

 , , ,


0

1

После двух лет мучений с отладкой веб-скриптов на python3, работающих как cgi и не выводящих кириллицу обычным принтом, я наконец нашел решение: http://pastebin.com/vQaUKjkE

Перехватываем вывод настоящего принта, encode-им его в utf-8 и потом уже выводим на экран.

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

Ну и может кому-то это пригодится :)

Хороший костыль, качественный. А не проще написать print, который будет енкодить строки, а затем передавать в оригинальный, и использовать его, без плясок с бубном?

import __builtin__
print_orig = __builtin__.print

def print(*a): print_orig(a[0].encode('utf8'), *a[1:])

__builtin__.print = print
как-то так, на глазок

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

а почему первый элемент всегда должен быть строкой у которой есть encode?

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

sergey-novikov ★★★
() автор топика

Не связано ли это с тем, что cgi-скрипты запускаются с LANG=C? Может проще нужную локаль задать?

NeXTSTEP ★★
()
Ответ на: комментарий от sergey-novikov

а почему первый элемент всегда должен быть строкой у которой есть encode?

Ну я же сказал - «на глазок».

Очевидный быстрофикс:

def print(*objects, **kwa):
    return print_orig(
        *tuple(obj.encode('utf-8') if isinstance(obj, unicode) else obj for obj in objects),
        **kwa)
Всяко лучше, чем та магия ктулху из ОП, которая выполняется к тому же при каждом обращении к print.

Virtuos86 ★★★★★
()

Да уж, за два года ты не смог обернуть sys.stdout или заюзать нормальные шаблоны. Вместо этого решено было сделать порно. Сирожа, такой, Сирожа.

baverman ★★★
()
Ответ на: комментарий от baverman

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

sergey-novikov ★★★
() автор топика
Ответ на: комментарий от Virtuos86


def print(*objects, **kwa):
    return print_orig(
        *tuple(obj.encode('utf-8') if isinstance(obj, unicode) else obj for obj in objects),
        **kwa)


Заменил на этот вариант.
По интерфейсу расползлись b'\n' на экране, пока нет времени разбираться где он распечатал байты не приведя их к строке.

Часть движка вообще вывела это вместо кириллицы:

\n\n\xd0\xb2\xd1\x80\xd0\xb5\xd0\xbc\xd1\x8f: 0 \xd0\xb4\xd0\xbd\xd0\xb5\xd0\xb9 0 \xd1\x87. 00 \xd0\xbc\xd0\xb8\xd0\xbd. 00 \xd1\x81\xd0\xb5\xd0\xba

Замерил время отрисовки главной страницы - предложенный способ быстрее моего на 0.01.
Думаете это критично?

sergey-novikov ★★★
() автор топика
Последнее исправление: sergey-novikov (всего исправлений: 4)
Ответ на: комментарий от sergey-novikov

Безусловно, выбирать надо то решение, которое работает, то есть не моё :-). Тем более, что отладить его я не в состоянии, не имея проблемного кода на руках.

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

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

не, проблема с кириллицей заложена где-то в связке апач+питон/cgi

попробуй сделать скрипт с одной строчкой print('кириллица')
и запустить его через веб с помощью cgi апача

скрипт упадет с ошибкой декодинга

я много чего раньше пробовал - системные кодировки и тп
помогал только encode строк

sergey-novikov ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.