Форум сайта python.su
Тут где-то человек употребляющий наркотики мелькал - честно, я наверно завидую ему - жизнь в розовом свете. К несчастью в реальной жизни есть кодировки… чего я уже только не читал…
Решил, по рекомендациям на сайте, использовать utf-8, блин, как бабушка пошептала, столько проблем исчезло…, и вот получил исключение в пакете logging…
уж казалось бы, библиотечный модуль и на тебе… может просто, чтобы жизнь медом не казалась….
проблема в следующем: win32, скрипт в utf-8, но логи (файл) должны писаться в windows-1251 (cp1251 по нашему), всякие там info, error, warning (стандартные функции logger'а) работают на ура, но вот exception…
ведь к тому, как exception (стандартная, опять же, функция logger'а) я не имею ни какого отношения….
уточню, лог выводится на консоль и в файл, файл - это FileHandler с параметром encoding=“cp1251” (повторюсь, скрипт coding: utf-8)… творится нечто непонятное, часть выводиводится на консоль, но возникает исключение при записи в файл, а периодически не выводмтся ни на консоль ни в файл….
ну и тут я почти как, Достоевский: кто виноват и что делать… ну достало уже….
PS: Python 2.4.x и Python 2.6.x
Отредактировано (Янв. 13, 2009 15:24:32)
Офлайн
Выложи работающий и не работающий примеры.
..bw
Офлайн
bwЕсли это адресованно мне, то я, право, затрудняюсь с ответом… exception вещь не предсказуемая :(
Выложи работающий и не работающий примеры.
..bw
Офлайн
К тебе (вам).
..bw
Офлайн
Вот банальный пример:
# -*- mode: python; coding: utf-8 -*-
from __future__ import print_function, division
"""
"""
#####################################################################################
import os, sys
import logutils
#####################################################################################
def main () :
log = logutils.getLogger()
try :
raise RuntimeError(u"Проверка связи")
except :
log.exception("")
#####################################################################################
if __name__ == "__main__" :
logutils.set_logger("test.log")
main()
#################################### End Of File ####################################
# logutils.py
# -*- mode: python; coding: utf-8 -*-
"""
по большей части автор модуля Андрей Светлов
"""
#####################################################################################
import os, sys
import logging, logging.handlers
#####################################################################################
for name in dir(logging) :
if not name.startswith('_') :
globals()[name] = getattr(logging, name)
#####################################################################################
def _get_instance_name (instance) :
return instance.__class__.__module__ + "." + instance.__class__.__name__ + ".0x.." + hex(id(instance))[-2:]
class class_logger (object) :
'''Class logger descriptor'''
def __init__ (self, name=None) :
self._logger = None
self._name = name
def __get__ (self, instance, owner) :
if self._logger is None:
if self._name is None:
self._name = owner.__module__ + "." + owner.__name__
self._logger = logging.getLogger(self._name)
return self._logger
class instance_logger (object) :
'''Instance logger descriptor'''
def __init__ (self, name=None) :
self._logger = None
self._name = name
def __get__ (self, instance, owner) :
assert instance is not None
if self._logger is None:
if self._name is None:
self._name = _get_instance_name(instance)
self._logger = logging.getLogger(self._name)
return self._logger
def set_logger (fname="", level=DEBUG, maxSize=5242880, viewName=True, backupCount=0) :
namestr = ""
if viewName :
if sys.version_info[:2] == (2, 4) :
namestr = "%(name)s#"
else :
namestr = "%(name)s.%(funcName)s#"
_console = logging.StreamHandler(sys.stdout)
_console.setLevel(level)
formatter = logging.Formatter(namestr + "%(message)s")
_console.setFormatter(formatter)
log = getLogger("")
log.addHandler(_console)
_file = None
if fname :
if maxSize > 0 :
_file = logging.handlers.RotatingFileHandler(fname, "ab", maxSize, backupCount, encoding="cp1251")
else :
_file = logging.FileHandler(fname, "ab", encoding="cp1251")
_file.setLevel(level)
formatter = logging.Formatter("%(asctime)s#" + namestr + "%(levelname)s#%(message)s")
_file.setFormatter(formatter)
log.addHandler(_file)
log.setLevel(level)
return (_console, _file)
def close_logger (handlers) :
log = getLogger("")
for handler in handlers :
if handler :
handler.flush()
handler.close()
log.removeHandler(handler)
#################################### End Of File ####################################
Офлайн
В принципе, это конечно не критично, есть модуль traceback, на сайте activestate есть модуль safe_unicode (к своему стыду дорлжен признаться, что ссылку не помню, но там хорошо работает поиск :))
т.е. все можно обойти, правда потребуются лишние телодвижения…
Офлайн
Доброго времени суток!
Что-то у меня вообще все сломалось :(
Python 2.6 (2.4), Windows XP SP3 локаль русская.
вот небольшой кусок кода:
# -*- mode: python; coding: utf-8 -*-
from __future__ import print_function, division
import codecs, os, sys
sys.stdout = codecs.getwriter('cp866')(sys.stdout, errors='replace')
import logging, logging.handlers
if "__main__" == __name__ :
log = logging.getLogger()
_console = logging.StreamHandler(sys.stdout)
_console.setLevel(logging.DEBUG)
log.addHandler(_console)
_file = logging.handlers.RotatingFileHandler("test.log", "ab", 5242880, 0, encoding="cp1251")
_file.setLevel(logging.DEBUG)
log.addHandler(_file)
log.setLevel(logging.DEBUG)
## пробуем, что получилось
log.info(u"Проба пера")
_file.flush()
_file.close()
log.removeHandler(_file)
_console.flush()
_console.close()
log.removeHandler(_console)
Traceback (most recent call last):
File "C:\Python26\lib\logging\__init__.py", line 765, in emit
self.stream.write(fs % msg.encode("UTF-8"))
File "C:\Python26\lib\codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
File "C:\Python26\lib\encodings\cp866.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 14: ordinal
not in range(128)
Traceback (most recent call last):
File "C:\Python26\lib\logging\__init__.py", line 765, in emit
self.stream.write(fs % msg.encode("UTF-8"))
File "C:\Python26\lib\codecs.py", line 686, in write
return self.writer.write(data)
File "C:\Python26\lib\codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
File "C:\Python26\lib\encodings\cp1251.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 43: ordinal
not in range(128)
root.<module>#Проба пера!
Traceback (most recent call last):
File "C:\Python26\lib\logging\__init__.py", line 765, in emit
self.stream.write(fs % msg.encode("UTF-8"))
File "C:\Python26\lib\codecs.py", line 686, in write
return self.writer.write(data)
File "C:\Python26\lib\codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
File "C:\Python26\lib\encodings\cp1251.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 43: ordinal
not in range(128)
try:
msg = self.format(record)
fs = "%s\n"
if isinstance(msg, unicode) :
self.stream.write(fs % msg)
else:
self.stream.write(fs % msg.decode(self.stream.encoding)) # здесь бы по идее подставить кодировку сообщения, но как ее угадаешь :)
self.flush()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
Офлайн