Comments 35
это:
logging.getLogger().addHandler(setupcon.ColoredLogger())
вот так:
logging.getLogger().addHandler(setupcon.ColoredHandler())
?
logging.getLogger().addHandler(setupcon.ColoredLogger())
вот так:
logging.getLogger().addHandler(setupcon.ColoredHandler())
?
Ох. С этим в питоне всегда столько секса. Помню в QT мучался. Там был какой то хак, не знаю что он такого делал, но после этого все работало
reload(sys)
sys.setdefaultencoding('utf-8')
Когда же начнется переход на Py3…
Для логов есть полустандартный велосипед pypi.python.org/pypi/logutils/
Раскрашивает консоль, помимо всего прочего.
Использовать reload(sys) и sys.setdefaultencoding(...) — дурной тон.
Одно то, что site убирает эту функцию из модуля — должно непрозрачно намекать, что разработчики языка хотели максимально ограничить использование setdefaultencoding. Не стоит гладить кошку против шерсти.
Раскрашивает консоль, помимо всего прочего.
Использовать reload(sys) и sys.setdefaultencoding(...) — дурной тон.
Одно то, что site убирает эту функцию из модуля — должно непрозрачно намекать, что разработчики языка хотели максимально ограничить использование setdefaultencoding. Не стоит гладить кошку против шерсти.
Ну, да, получил тот же велосипед, «но свой» :) Как оправдание — мой таки одноколёсный и в абстрактном сферическом линуксе не тянет за собой ничего стороннего. По большому счёту статья — заметка на память, дабы каждый раз не искать «и как же оно там делалось-то».
Про reload — согласен, а толку… Если то же Qt норовил (боролся в pyQt 4.6.что-то, дальше не знаю) воспользоваться именно sys.getdefaultencoding() и корёжить всякий ввод/вывод. Можно сделать reload опцией, например…
Про reload — согласен, а толку… Если то же Qt норовил (боролся в pyQt 4.6.что-то, дальше не знаю) воспользоваться именно sys.getdefaultencoding() и корёжить всякий ввод/вывод. Можно сделать reload опцией, например…
Нет версии для Win64.
Удивительно встретить на просторах Хабра статью о скрипте для самиздата — тоже ваял его для себя, правда, в итоге добавил Qt-шный интерфейс и выложил.
Чем СИшные страницы парсите?
Чем СИшные страницы парсите?
Начинал с BeautifulSoap. Тормоз и глюкало :(
В работающей версии — re+lxml+неработающий гуй на Qt (фактически иконка в трее и окно настроек частоты проверки), тем более что lxml даёт более подходящий мне diff на html-e. Какая-то версия этого дела даже лежит в гуглокоде. Там, кажись только re и htmldiff+ElementTree на генерацию diff-ов и нговостей (http://code.google.com/p/py-samizdat/)
В неспешно пишущейся сейчас — ручной разбор строк, re, HTMLParser. Во что выльется дальше — пока не ясно…
ЗЫ: я те только качаю новости, но и выкачиваю тексты чтоб не потерять, если автор убирает произведение…
В работающей версии — re+lxml+неработающий гуй на Qt (фактически иконка в трее и окно настроек частоты проверки), тем более что lxml даёт более подходящий мне diff на html-e. Какая-то версия этого дела даже лежит в гуглокоде. Там, кажись только re и htmldiff+ElementTree на генерацию diff-ов и нговостей (http://code.google.com/p/py-samizdat/)
В неспешно пишущейся сейчас — ручной разбор строк, re, HTMLParser. Во что выльется дальше — пока не ясно…
ЗЫ: я те только качаю новости, но и выкачиваю тексты чтоб не потерять, если автор убирает произведение…
Есть очень простое решение — не писать на питоне.
Есть и еще более простое — не писать. Тогда эффект «кривых рук» никак не проявится.
К тому, что виндоус — говно (во многих местах), питон отношения не имеет. Если бы его создатели думали мозгом больше, то проблем было бы меньше. Консольное окошко — это просто изделие века. Миксовать 3 разных кодировки по системе — это супер.
таки logging всёравно же будет вызывать __repr__ или __str__ для конвертирования объектов в строку.
ваши махинации с консолью спасут от необходисомти везде лепить
ваши махинации с консолью спасут от необходисомти везде лепить
__repr__ = lambda self: unicode(self).encode("utf-8")
?тоесть даже
unicode(self).encode(get_whatever_console_encoding())
для кросплатформизма.Ничего не понял. Для каких-таких объектов будет вызываться __str__ или __repr__?
например, для
logging.debug(«foo=%s»,MyClass(u«блабла»))
logging.debug(«foo=%s»,{'foo': MyClass(u«блабла»)})
logging.debug(«foo=%s»,ForeignClass(MyClass(u«блабла»)))
насколько я понимаю, в первом случае вызовется Foo.__str__ из logger
во втором — изнутри dict.__repr__ и там уже непонятно repr или str
в третьем случае может случиться вобще всё что угодно.
(такой случай происходит, например, при рисовании графа сделанного networx через graphviz)
logging.debug(«foo=%s»,MyClass(u«блабла»))
logging.debug(«foo=%s»,{'foo': MyClass(u«блабла»)})
logging.debug(«foo=%s»,ForeignClass(MyClass(u«блабла»)))
насколько я понимаю, в первом случае вызовется Foo.__str__ из logger
во втором — изнутри dict.__repr__ и там уже непонятно repr или str
в третьем случае может случиться вобще всё что угодно.
(такой случай происходит, например, при рисовании графа сделанного networx через graphviz)
Достаточно иметь
logging.debug(u'foo=%s', 'string')
Logging handler (или stream для StreamHandler, например) должен знать, как преобразовать юникод в байты для дальнейшего использования.
Преобразование объектов, выполняемое для форматирования строк — не забота системы логирования.
Тем не менее создание необходимых __unicode__ (если мы говорим о python 2.x) не считаю чем-то сложным или непонятным.
logging.debug(u'foo=%s', 'string')
Logging handler (или stream для StreamHandler, например) должен знать, как преобразовать юникод в байты для дальнейшего использования.
Преобразование объектов, выполняемое для форматирования строк — не забота системы логирования.
Тем не менее создание необходимых __unicode__ (если мы говорим о python 2.x) не считаю чем-то сложным или непонятным.
Я уж надеялся, что это полное решение проблемы Юникода в Python под Windows…
То есть я хочу сказать, что печатать Юникод в консоль Windows можно. И не ограничиваясь системной (или какой-то одной) восьмибитной кодировкой. Для этого есть соответствующие API. А Python использует stdout, который идёт из стандартной библитеки Си, которая все эти приколы Windows не знает.
То есть я хочу сказать, что печатать Юникод в консоль Windows можно. И не ограничиваясь системной (или какой-то одной) восьмибитной кодировкой. Для этого есть соответствующие API. А Python использует stdout, который идёт из стандартной библитеки Си, которая все эти приколы Windows не знает.
Python использует GetStdHandle(STD_OUTPUT_HANDLE) в качестве stdout.
Это — обычный дескриптор. Работает с байтами (WriteFile и так далее).
Где там Unicode API?
stdout — это ведь не всегда консоль!
Это — обычный дескриптор. Работает с байтами (WriteFile и так далее).
Где там Unicode API?
stdout — это ведь не всегда консоль!
Python/sysmodule.c
PyObject *
_PySys_Init(void)
{
//...
sysin = PyFile_FromFile(stdin, "", "r", NULL);
sysout = PyFile_FromFile(stdout, "", "w", _check_and_flush);
syserr = PyFile_FromFile(stderr, "", "w", _check_and_flush);
//...
}
А вы что нашли?
Эти функции корректно работают с Юникодом. Кодовая страница не имеет никакого значения (хотя на терминале охвата шрифтов не хватит для всего Юникода). Попробуйте, скажем:
import ctypes
ctypes.windll.msvcrt._putwch(1093)
Ну хорошо, это файл. Только к чему вы это сказали? Проверить, что это на самом деле, во время выполнения - не так сложно.
Я попытался вспомнить, как создается stdout в CRT. А сверху — да. Файлы из стандартной библиотеки.
Теперь займемся предложенными функциями из console io.
Скрестить их и sys.stdout (который в питоне полноценный файл по определению) не совсем легко.
Насколько я помню, в последний раз это обсуждалось в python-dev прошедшими весной-летом — и ни к чему не пришли.
Получалось, что если запустили не в консоли — то stdout прикидывается файлом (pipe на самом деле, сейчас не важно). А если консоль — то уже не файл а console io. Со своими тараканами.
Выходило, что полной совместимости и прозрачности так не добиться. На Windows свои штучки, на Posix — свои.
И если уж не получается сделать так, чтобы один и тот же код работал везде одинаково — то не стоит предлагать полурабочее решение.
Если хочется работать с console io — следует делать import msvcrt, там все есть. Оборачивать их в file-like object (или io.TextIOBase для тройки) и подставлять в sys.stdout. Проблемы, способные выползти при subprocess.Popen(..., stdout=subprocess.PIPE), например — пусть разработчик решает сам. Или что там еще может произойти при вызове C Extension, которая печатает в CRT stdout.Если что-то поломается — пусть будут виноваты не внутренности Питона, а программист в явном виде.
Быть может когда-нибудь найдется разработчик, который починит всё-всё-всё. Пока такого нет, а возможные неоднозначности при решении «в лоб» — есть. И различных аспектов, неочевидных при беглом осмотре — очень много.
Еще раз повторюсь: тема консоли и юникода для Windows возникает регулярно. И спецы, съевшие на этом деле не один пуд соли, вываливали десятки специфических случаев в которых простое решение не работало. Я этим спецам верю.
Теперь займемся предложенными функциями из console io.
Скрестить их и sys.stdout (который в питоне полноценный файл по определению) не совсем легко.
Насколько я помню, в последний раз это обсуждалось в python-dev прошедшими весной-летом — и ни к чему не пришли.
Получалось, что если запустили не в консоли — то stdout прикидывается файлом (pipe на самом деле, сейчас не важно). А если консоль — то уже не файл а console io. Со своими тараканами.
Выходило, что полной совместимости и прозрачности так не добиться. На Windows свои штучки, на Posix — свои.
И если уж не получается сделать так, чтобы один и тот же код работал везде одинаково — то не стоит предлагать полурабочее решение.
Если хочется работать с console io — следует делать import msvcrt, там все есть. Оборачивать их в file-like object (или io.TextIOBase для тройки) и подставлять в sys.stdout. Проблемы, способные выползти при subprocess.Popen(..., stdout=subprocess.PIPE), например — пусть разработчик решает сам. Или что там еще может произойти при вызове C Extension, которая печатает в CRT stdout.Если что-то поломается — пусть будут виноваты не внутренности Питона, а программист в явном виде.
Быть может когда-нибудь найдется разработчик, который починит всё-всё-всё. Пока такого нет, а возможные неоднозначности при решении «в лоб» — есть. И различных аспектов, неочевидных при беглом осмотре — очень много.
Еще раз повторюсь: тема консоли и юникода для Windows возникает регулярно. И спецы, съевшие на этом деле не один пуд соли, вываливали десятки специфических случаев в которых простое решение не работало. Я этим спецам верю.
А разве стандартная библиотека C, в свою очередь, не оборачивает тот самый Console IO?
Мы говорим о _putwch или fwrite?
О stdout или таки о console io?
О stdout или таки о console io?
Стандартная библиотека C, то бишь fwrite и компания, не есть самый низкий уровень. Она же построена поверх чего-то.
Было бы странно, если текст в консоль попадал принципиально иными путями. Мне кажется, это все равно в итоге сводится к Console IO.
Было бы странно, если текст в консоль попадал принципиально иными путями. Мне кажется, это все равно в итоге сводится к Console IO.
_putch превращается в WriteConsoleW (возвращаясь к WriteConsoleA есть WriteConsoleW возвращает ERROR_CALL_NOT_IMPLEMENTED — кажется возможно только на Win9x).
fwrite — это WriteFile с буферизацией.
Довольно разные штуки. Т.е. если есть handle для stdout — с ним можно работать через file api или через console api (оба из kernel32). Они очень слабо пересекаются. Смешивать способы настоятельно не рекомендуется.
fwrite — это WriteFile с буферизацией.
Довольно разные штуки. Т.е. если есть handle для stdout — с ним можно работать через file api или через console api (оба из kernel32). Они очень слабо пересекаются. Смешивать способы настоятельно не рекомендуется.
а cygwin использовать, не?
Sign up to leave a comment.
Как я боролся с кодировками в консоли