1

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

このように、ログには失敗したデータを示す行が含まれ、失敗したログ行ごとに 1 行が表示されます。その後、ログ ファイルを調べると、問題のある行がいくつか見つかる場合があります。

デバッグが完了したら元に戻せるように、logging/__init__.py ファイルの元のバージョンを保持することを忘れないでください。

この問題の難しい部分は、問題のある行がコード全体に散りばめられている可能性があり、100% のコード カバレッジがあり、すべてのコードをヒットすることを保証できない限り、このようなアドホック手法ですべてをキャッチすることはできないことです。テスト中。

Python における Unicode の根本的な問題の詳細については、Pragmatic Unicode または How Do I Stop The Pain? を参照してください。.

于 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 に答える