我正在尝试使用 Python 的日志记录包将 UTF-8 编码的字符串记录到文件中。作为一个玩具示例:
import logging
def logging_test():
handler = logging.FileHandler("/home/ted/logfile.txt", "w",
encoding = "UTF-8")
formatter = logging.Formatter("%(message)s")
handler.setFormatter(formatter)
root_logger = logging.getLogger()
root_logger.addHandler(handler)
root_logger.setLevel(logging.INFO)
# This is an o with a hat on it.
byte_string = '\xc3\xb4'
unicode_string = unicode("\xc3\xb4", "utf-8")
print "printed unicode object: %s" % unicode_string
# Explode
root_logger.info(unicode_string)
if __name__ == "__main__":
logging_test()
这会在 logging.info() 调用上引发 UnicodeDecodeError。
在较低级别,Python 的 logging 包使用 codecs 包打开日志文件,传入“UTF-8”参数作为编码。这一切都很好,但它试图将字节字符串写入文件而不是 unicode 对象,这会爆炸。本质上,Python 就是这样做的:
file_handler.write(unicode_string.encode("UTF-8"))
什么时候应该这样做:
file_handler.write(unicode_string)
这是 Python 中的一个错误,还是我在服用疯狂的药丸? FWIW,这是一个普通的 Python 2.6 安装。
最佳答案
代码如下:
raise Exception(u'щ')
原因:
File "/usr/lib/python2.7/logging/__init__.py", line 467, in format
s = self._fmt % record.__dict__
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
这是因为格式字符串是字节字符串,而一些格式字符串参数是非 ASCII 字符的 unicode 字符串:
>>> "%(message)s" % {'message': Exception(u'\u0449')}
*** UnicodeEncodeError: 'ascii' codec can't encode character u'\u0449' in position 0: ordinal not in range(128)
将格式字符串设为 unicode 可以解决问题:
>>> u"%(message)s" % {'message': Exception(u'\u0449')}
u'\u0449'
因此,在您的日志记录配置中,将所有格式字符串设为 unicode:
'formatters': {
'simple': {
'format': u'%(asctime)-s %(levelname)s [%(name)s]: %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
},
...
并修补默认的 logging
格式化程序以使用 unicode 格式字符串:
logging._defaultFormatter = logging.Formatter(u"%(message)s")
关于python - UTF-8 在 Python 日志记录中,如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1545263/