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

问题描述 投票:7回答:9

完全被现在混淆了......我正在开发python / django并使用python日志记录。我的所有应用程序都需要unicode,我的所有模型都只有一个unicode()`,返回你'''方法。现在,在登录时,我遇到了一个非常奇怪的问题,它花了很长时间才发现我可以重现它。我已经尝试过Py 2.5.5和Py 2.6.4以及同样的事情。所以

每当我做一些直接记录时,如:

logging.debug(u'new value %s' % group) 

这会调用模型group.unicode():return unicode(group.name)

我的unicode方法看起来像这样:

def __unicode__(self):
    return u'%s - %s (%s)' % (self.group, self.user.get_full_name(), self.role)

即使group.name为XXX或ÄÄ(需要unicode),这也适用。但是当我出于某种原因想要记录集合,列表,字典,django-query集合以及例如单个实例时。列表可能是unicode或不是我遇到麻烦...

每当group.name需要像Luleå(我的家乡)这样的unicode时,这会给我一个UnicodeDecodingError

logging.debug(u'new groups %s' % list_of_groups)

通常我得到这样的错误:

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)')

但是,如果我做print list_of_groups终端上的一切都很好

所以,我的理解是列表开始生成自己并对其所有元素执行repr()并返回它们的值 - 在这种情况下它应该是's2 | ÅÄÖÖ',然后列表呈现为(ascii,列表中的东西),然后当尝试将ascii解码为unicode时,这当然不起作用 - 因为列表中的一个元素已经回归当repr完成时,你自己就是一个'...'。

但是为什么这个????'

为什么每当我记录group.name之类的简单事物以及调用unicode方法时,事情都能正常处理并且unicode / ascii被正确处理。每当我变得懒惰并且想要记录列表时,无论何时遇到unicode字符,设置或其他事情都会变坏...

一些工作和失败的例子。如果group.name我去模型领域和group称为__unicode__()

    logging.debug("1. group: %s " % group.name) # WORKS
    logging.debug(u"2. group: %s " % group) # WORKS
    logging.debug("3. group: %s " % group) # FAILS
    logging.debug(u"4. group: %s " % group.name) # WORKS
    logging.debug("5. group: %s " % group.name) # WORKS

...我真的以为我抓住了Unicode ;-(

python django logging unicode decoding
9个回答
2
投票

这是我的测试代码:

#-*- 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的声明更改为:def repr(self):return 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)

所以看起来对象层次结构中的某个人有一个repr()实现,它错误地返回一个unicode字符串而不是一个普通的字符串。正如其他人提到的,当你做一个格式字符串时

'format %s' % mylist

和mylist是一个序列,python自动调用它上面的repr()而不是unicode()(因为没有“正确”的方式将列表表示为unicode字符串)。

这可能是django在这里有问题,或者你可能在你的一个模型中错误地实现了__repr__

#

1
投票

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

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å
>>> 

因此,正如丹尼尔所说,在你传递给日志记录时,可能存在一些不合适的Unicode。

此外,我不知道您正在使用哪些处理程序,但确保是否有文件处理程序明确指定要使用的输出编码,如果有流处理程序,您还要使用编码来包装任何需要它的输出流由codecs模块提供的包装器(并将包装的流传递给日志记录)。


1
投票

尝试在views.py的顶部使用此代码

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

0
投票

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

所以,我的理解是列表开始生成自己并对其所有元素执行repr()并返回它们的值 - 在这种情况下它应该是's2 | ÅÄÖÖ',然后列表呈现为(ascii,列表中的东西),然后当尝试将ascii解码为unicode时,这当然不起作用 - 因为列表中的一个元素已经回归当repr完成时,你自己就是一个'...'。

准确地解释了发生了什么 - 输出列表与打印其所有元素不同,因为在引擎盖下它所做的只是在列表中的每个元素上调用repr()。您可以记录列表推导而不是输出原始列表,该列表推导在每个元素上调用unicode,这将修复它。


0
投票

在尝试记录set / list / dict / django queryset时,我结束了以下建议,并回答了所有代码并进行了列表理解或类似操作。所以适应和添加这样的东西解决了它:

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

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


0
投票

你试过手动制作任何结果unicode吗?

logging.debug(u'new groups %s' % unicode(list_of_groups("UTF-8"))

0
投票

我遇到了同样的问题:请参阅http://hustoknow.blogspot.com/2012/09/unicode-quirks-in-django.html

您可以声明str()方法来覆盖Django默认行为,这将有助于避免此问题。或者你总是必须在你的logging()语句前面加上u'前缀。


0
投票

校验:

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,修复了俄语问题


0
投票

我认为,这个Python的错误是描述行为的原因https://bugs.python.org/issue19846检查语言环境设置,如果你在Python 3上得到UnicodeDecodeError。

这个答案https://stackoverflow.com/a/40803148/4862792帮助我的窗口,但在生产与语言环境LANG_C我再次遇到这个问题

© www.soinside.com 2019 - 2024. All rights reserved.