7

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

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

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

这称为模型组。unicode ():返回 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, the-stuff-in-the-list),然后在尝试将ascii解码为 un​​icode 时,这当然行不通——因为列表中的一个元素已恢复当对它进行repr 时,你'...' 本身。

但这是为什么呢????

以及为什么当我记录诸如 group.name 等或 group 之类的简单内容并且调用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 ;-(

4

9 回答 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__在其中一个模型中实现不正确。

#
于 2010-09-17T00:11:55.553 回答
1

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

Python 2.6.4(r264:75706,2009 年 12 月 7 日,18:45:15)
[GCC 4.4.1] 在 linux2 上
输入“帮助”、“版权”、“信用”或“许可”以获取更多信息。
>>> 导入日志
>>> group = u'Luleå'
>>> logging.warning('Group: %s', group)
WARNING:root:Group: Luleå
>>> logging.warning(u'Group: %s', group)
WARNING:root:Group: Luleå
>>>

因此,正如丹尼尔所说,在您传递给日志记录的内容中可能存在不正确的 Unicode。

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

于 2010-01-21T20:18:49.590 回答
1

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

#-*- coding: utf-8 -*-
...
于 2010-05-06T07:30:10.937 回答
0

您是否尝试过手动制作任何结果 unicode?

logging.debug(u'new groups %s' % unicode(list_of_groups("UTF-8"))
于 2010-08-11T06:42:54.707 回答
0

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

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

于 2012-09-21T14:58:24.997 回答
0

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

所以,我的理解是列表开始自己生成并对其所有元素执行 repr() 并返回它们的值 - 在这种情况下它应该是 's2 | ÅÄÖÖ',然后列表将自身显示为 (ascii, the-stuff-in-the-list),然后在尝试将 ascii 解码为 un​​icode 时,这当然行不通——因为列表中的元素之一已恢复当对它进行repr 时,你'...' 本身。

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

于 2010-01-21T20:10:10.460 回答
0

在尝试记录 set/list/dict/django 查询集时,我按照已回答的建议结束了所有代码并进行了列表理解或类似操作。所以适应和添加这样的东西为我解决了这个问题:

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

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

于 2010-01-22T09:36:30.453 回答
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,修复了俄语语言的问题

于 2016-11-25T10:47:14.537 回答
0

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

这个答案https://stackoverflow.com/a/40803148/4862792对 Windows 有帮助,但是在使用语言环境 LANG_C 进行生产时,我又遇到了这个问题

于 2019-03-14T05:43:35.593 回答