1

在将一个遗留 Django 项目(基于 Django 1.1)本地化为日语后,当语言环境为日语时,一些日志(不是全部)正在输出如下内容:

Traceback (most recent call last):
  File "/home/deploy/.pythonbrew/pythons/Python-2.7/lib/python2.7/logging/__init__.py", line 838, in emit
    msg = self.format(record)
  File "/home/deploy/.pythonbrew/pythons/Python-2.7/lib/python2.7/logging/__init__.py", line 715, in format
    return fmt.format(record)
  File "/home/deploy/.pythonbrew/pythons/Python-2.7/lib/python2.7/logging/__init__.py", line 467, in format
    s = self._fmt % record.__dict__
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)

这可能是什么原因,有没有简单的方法来规避这个问题?如果没有,我该如何更仔细地调查这个问题,因为我什至不知道哪些行调用了失败的日志?提前致谢。

4

2 回答 2

3

找出字符串是什么的方法是编辑日志记录模块,为您提供有关错误的一些信息。您不必保留编辑,只需修改它们足够长的时间以找出导致问题的原因。

例如,在“/home/deploy/.pythonbrew/pythons/Python-2.7/lib/python2.7/logging/__init__.py”中,第 467 行是这一行:

s = self._fmt % record.__dict__

将其更改为:

try:
    s = self._fmt % record.__dict__
except UnicodeError:
    import pdb
    pdb.set_trace()

然后当 UnicodeDecodeError 发生时,您将被放入调试器中。您可以检查格式字符串和记录以确定问题所在。

不过,这可能太费力了,所以另一种选择是:

try:
    s = self._fmt % record.__dict__
except UnicodeError:
    s = "*** Couldn't log properly: %r against %r" % (self._fmt, record.__dict__)

这样,日志将包含一行指示失败的数据,并且每个失败的日志行都有一个。如果您随后检查日志文件,您可能会发现许多问题行。

不要忘记保留 logging/__init__.py 文件的原始版本,以便在完成调试时可以恢复到它。

这个问题的难点在于,可能有许多违规行,散布在你的代码中,除非你有 100% 的代码覆盖率并且可以保证命中所有他们在测试期间。

有关 Python 中 Unicode 潜在问题的更多信息,请参阅Pragmatic Unicode,或者,如何停止痛苦?.

于 2012-07-13T12:45:11.737 回答
0

为了避免这种异常,我在每个 .py 的顶部写下这一行:

# This Python file uses the following encoding: utf-8

来自PEP

  1. 没有解释器行,使用纯文本:

      # This Python file uses the following encoding: utf-8
      import os, sys
      ...
    
于 2012-07-13T12:49:13.467 回答