在django和unicode中使用python日志时出现问题

在django和unicode中使用python日志时出现问题,python,django,logging,unicode,decoding,Python,Django,Logging,Unicode,Decoding,现在完全搞糊涂了。。。我正在使用python/django进行开发,并使用python日志记录。我的所有应用程序都需要unicode,我的所有型号都只实现了一个unicode()`,返回u'..'方法。现在在记录日志时,我遇到了一个非常奇怪的问题,花了很长时间才发现我可以复制它。我已经试过Py 2.5.5和Py 2.6.4以及同样的东西。所以 每当我做一些直接的日志记录时,比如: logging.debug(u'new value %s' % group) 这将调用models组。unico

现在完全搞糊涂了。。。我正在使用python/django进行开发,并使用python日志记录。我的所有应用程序都需要unicode,我的所有型号都只实现了一个unicode()`,返回u'..'方法。现在在记录日志时,我遇到了一个非常奇怪的问题,花了很长时间才发现我可以复制它。我已经试过Py 2.5.5和Py 2.6.4以及同样的东西。所以

每当我做一些直接的日志记录时,比如:

logging.debug(u'new value %s' % group) 
这将调用models组。unicode():返回unicode(group.name)

我的unicode方法如下所示:

def __unicode__(self):
    return u'%s - %s (%s)' % (self.group, self.user.get_full_name(), self.role)
Exception Type:     UnicodeDecodeError
Exception Value:    ('ascii',  '<RBACInstanceRoleSet: s2 | \xc3\x84\xc3\x96\xc3\x96\xc3\x85\xc3\x85\xc3\x85 Gruppen>]', 106, 107, 'ordinal not in range(128)')
即使group.name是XXX或ÄÄÄ(需要unicode)也可以使用。但是,当我出于某种原因想要记录一个集合、列表、字典、django查询集合和单个实例时,例如,列表可能是unicode或不是unicode,我就会遇到麻烦

因此,每当group.name需要像Luleå(我的家乡)这样的unicode时,我就会遇到unicode编码错误

通常会出现如下错误:

def __unicode__(self):
    return u'%s - %s (%s)' % (self.group, self.user.get_full_name(), self.role)
Exception Type:     UnicodeDecodeError
Exception Value:    ('ascii',  '<RBACInstanceRoleSet: s2 | \xc3\x84\xc3\x96\xc3\x96\xc3\x85\xc3\x85\xc3\x85 Gruppen>]', 106, 107, 'ordinal not in range(128)')

…我真的认为我掌握了Unicode-(

如果你明白我的意思,我不明白你不明白的是什么。你的中间段:

因此,我的理解是列表开始生成自己,并对其所有元素执行repr(),它们返回它们的值——在本例中,它应该是“s2 |ÄÖ”,然后列表显示为(ascii,列表中的内容)然后,当试图将ascii码解码为unicode码时,这当然不起作用——因为列表中的一个元素在对其执行repr时已经返回了一个u'…'


准确地解释正在发生的事情-输出列表与打印其所有元素不同,因为在后台它所做的只是调用repr()在列表中的每个元素上。不输出原始列表,您可以在每个元素上记录调用unicode的列表理解,这将修复它。

我无法通过简单的测试重现您的问题:

Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15) [GCC 4.4.1] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import logging >>> group = u'Luleå' >>> logging.warning('Group: %s', group) WARNING:root:Group: Luleå >>> logging.warning(u'Group: %s', group) WARNING:root:Group: Luleå >>> Python 2.6.4(r264:757062009年12月7日18:45:15) [GCC 4.4.1]关于linux2 有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。 >>>导入日志记录 >>>组=u'Luleå' >>>日志记录。警告('组:%s',组) 警告:root:Group:Luleå >>>日志记录。警告(u'组:%s',组) 警告:root:Group:Luleå >>> 所以,正如Daniel所说,在您传递给日志的内容中,可能存在一些不适合Unicode的内容


另外,我不知道您使用的是什么处理程序,但请确保是否有明确指定要使用的输出编码的文件处理程序,如果有流处理程序,您还可以使用编码包装器包装任何需要的输出流,如
编解码器
模块提供的编码包装器(并将包装后的流传递给日志记录).

在尝试记录set/list/dict/django查询集时,我结束了以下建议的回答,并检查了所有代码和执行列表理解或类似操作。因此,修改和添加类似的内容为我解决了这一问题:

logging.debug(u"new groups: %s" % [unicode(g) for g in list_of_groups])

所以现在我要做的就是永远不要忘记做这件事;-)

试着在views.py的顶部使用这段代码

#-*- coding: utf-8 -*-
...

您是否尝试过手动生成任何结果

logging.debug(u'new groups %s' % unicode(list_of_groups("UTF-8"))
以下是我的测试代码:

#-*- coding: utf-8 -*-                                      
class Wrap:                                          
    def __init__(self, s): self.s = s
    def __repr__(self): return repr(self.s)    
    def __unicode__(self): return unicode(self.s)
    def __str__(self): return str(self.s)

s = 'hello'  # a plaintext string
u = 'ÅÄÖÖ'.decode('utf-8') 
l = [s,u]
test0 = unicode(repr(l))
test1 = 'string %s' % l
test2 = u'unicode %s' % l
当您运行它时,上面的操作很好。但是,如果将repr的声明更改为: defrepr(self):返回unicode(self.s)

然后,它会中止,并执行以下操作:

Traceback (most recent call last):
  File "mytest.py", line 13, in <module> unicode(l)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3:
   ordinal not in range(128)
mylist是一个序列,python会自动对其调用repr(),而不是unicode()(因为没有“正确”的方法将列表表示为unicode字符串)

这可能是django的错,也可能是您在其中一个模型中错误地实现了
\uuu repr\uuu


# 我遇到了同样的问题:请参阅

您可以声明一个str()方法来覆盖Django默认行为,这将有助于避免此问题。或者您必须始终在日志()语句前面加上前缀u。

检查:

import locale
locale.getpreferredencoding()
必须是“utf8”。我有“cp1252”

帮助我添加到manage.py:

import _locale
_locale._getdefaultlocale = (lambda *args: ['en_US', 'utf8'])
Windows 10、Django 1.10.3、Python 3.5.2、,
修复了俄语的问题

我认为,Python的这个bug就是所描述行为的原因 如果在Python3上出现UnicodeDecodeError,请检查区域设置


这个答案对windows有帮助,但在使用locale LANG_C的生产中,我又遇到了一次这个问题

哦,忘了。我的生产站点使用postgres,我运行sqllite进行本地测试/开发,但在任何地方都存在相同的问题。您是否只在日志机制方面存在此问题。如果你评论它会发生什么?是的-只记录。打印相同的语句是好的,注释掉日志是好的。现在注意到logging.debug(组的列表)显示了很好的带有unicode字符的日志消息…是的,但我有点懒,希望能够输出任何东西;列表、字段。。我有很多带有警告/info/debug/error的代码,需要仔细检查每一条语句,如果是这样的话就进行修改。如果这就是需要的话……是的,还有另一件事,首先我只是试着做:logging.debug('new groups%s'%list\u of_groups)#突然工作,即删除u',然后list/set/dictionary都开始记录良好,但是我记录字段的所有其他语句都开始失败,并出现相同的错误。因此,例如,将不再工作:logging.debug('名称为%s的新组'%group.name)#FAILSyes,按照您的状态工作。但我的数据存储在django模型中,我处理这些实例,当打印名为的组(即模型类组的实例)时。。。还有很多其他的字段,我只是做打印模型——然后调用group的unicode方法来打印或记录自己。这总是适用于实例。但是当我有一个这样的实例的列表/集合/目录,并在debug.logging中输出它们时,如果其中一个实例返回unicode,事情就会崩溃。尽管如此,如果没有其他原因的话
import _locale
_locale._getdefaultlocale = (lambda *args: ['en_US', 'utf8'])