6

メッセージにUnicodeを含むPython2.7.xで例外を発生させようとしています。私はそれを機能させることができないようです。

エラーメッセージにUnicodeを含めることはサポートされていないか、推奨されていませんか?または、sys.stderrを確認する必要がありますか?

 # -*- coding: utf-8 -*-
 class MyException(Exception):
  def __init__(self, value):
    self.value = value
  def __str__(self):
    return self.value
  def __repr__(self):
    return self.value
  def __unicode__(self):
    return self.value

desc = u'something bad with field \u4443'

try:
  raise MyException(desc)
except MyException as e:
  print(u'Inside try block : ' + unicode(e))

# here is what i wish to make work 
raise MyException(desc)

スクリプトを実行すると、以下の出力が生成されます。私のtry/exceptの中で私は問題なく文字列を印刷することができます。

私の問題はtry/exceptの外にあります。

Inside try block : something bad with field 䑃
Traceback (most recent call last):
  File "C:\Python27\lib\bdb.py", line 387, in run
    exec cmd in globals, locals
  File "C:\Users\ghis3080\r.py", line 25, in <module>
    raise MyException(desc)
MyException: something bad with field \u4443

前もって感謝します。

4

3 に答える 3

2

これがPythonの仕組みです。あなたが見ているものはtraceback._some_string()Pythonコアライブラリから来ていると思います。そのモジュールでは、スタックトレースが実行されると、そのメソッドのコードは最初にを使用してメッセージを変換しようとしますstr()。次に、例外が発生した場合は、を使用してメッセージをunicode()変換し、次にを使用してASCIIに変換しencode("ascii", "backslashreplace")ます。有効な出力が得られ、すべてが正しく機能しています。Pythonは、実行しているプラ​​ットフォームに関係なく問題なく表示されるように、エラーメッセージを疑似ダウン変換するのが最善だと思います。これは、キャラクターのUnicodeコードポイントにすぎません。try/exceptこの変換はスタックトレースを生成するメカニズムに固有のものであるため(キャッチされていない例外の場合など)、ブロックでは発生しません。

于 2012-11-06T18:27:22.607 に答える
2

動作はPythonのバージョンと環境によって異なります。Python 3では、の文字​​エンコードエラーハンドラsys.stderrは常に'backslashreplace'次のとおりです。

from __future__ import unicode_literals, print_function
import sys

s = 'unicode "\u2323" smile'
print(s)
print(s, file=sys.stderr)
try:
    raise RuntimeError(s)
except Exception as e:
    print(e.args[0])
    print(e.args[0], file=sys.stderr)
    raise

python3:

$ PYTHONIOENCODING=ascii:ignore python3 raise_unicode.py
unicode "" smile
unicode "\u2323" smile
unicode "" smile
unicode "\u2323" smile
Traceback (most recent call last):
  File "raise_unicode.py", line 8, in <module>
    raise RuntimeError(s)
RuntimeError: unicode "\u2323" smile

python2

$ PYTHONIOENCODING=ascii:ignore python2 raise_unicode.py
unicode "" smile
unicode "" smile
unicode "" smile
unicode "" smile
Traceback (most recent call last):
  File "raise_unicode.py", line 8, in <module>
    raise RuntimeError(s)
RuntimeError

それは私のシステムでは、エラーメッセージはpython2で食べられます。

注:Windowsでは、次のことを試すことができます。

T:\> set PYTHONIOENCODING=ascii:ignore
T:\> python raise_unicode.py

比較のために:

$ python3 raise_unicode.py
unicode "⌣" smile
unicode "⌣" smile
unicode "⌣" smile
unicode "⌣" smile
Traceback (most recent call last):
  File "raise_unicode.py", line 8, in <module>
    raise RuntimeError(s)
RuntimeError: unicode "⌣" smile
于 2012-11-06T20:51:52.483 に答える
1

私の場合、あなたの例は正常に機能し、素敵なユニコードを出力しました。

ただし、Unicode文字なしで(またはエスケープ/バックスラッシュを使用して)出力された例外スタックで多くの問題が発生する場合があります。障害を克服し、通常のメッセージを印刷することが可能です。

出力に関する問題の例(Python 2.7、Linux):

# -*- coding: utf-8 -*-
desc = u'something bad with field ¾'
raise SyntaxError(desc.encode('utf-8', 'replace'))

切り捨てられたメッセージまたはねじ込まれたメッセージのみが出力されます。

~/.../sources/C_patch$ python SO.py 
Traceback (most recent call last):
  File "SO.py", line 25, in <module>
    raise SyntaxError(desc)
SyntaxError

変更されていないUnicodeを実際に表示するには、それをrawバイトにエンコードして、例外オブジェクトにフィードします。

# -*- coding: utf-8 -*-
desc = u'something bad with field ¾'
raise SyntaxError(desc.encode('utf-8', 'replace'))

今回は完全なメッセージが表示されます:

~/.../sources/C_patch$ python SO.py 
Traceback (most recent call last):
  File "SO.py", line 3, in <module>
    raise SyntaxError(desc.encode('utf-8', 'replace'))
SyntaxError: something bad with field ¾

必要に応じてコンストラクターで実行できますvalue.encode('utf-8', 'replace')が、システム例外を除いてraise、例のようにステートメントで実行する必要があります。

ヒントはここから得られます:欲求不満の克服:python2でユニコードを正しく使用します(多くのヘルパーを備えた大きなライブラリがあり、それらはすべて上記の例に分解できます)。

于 2014-11-27T11:48:39.457 に答える