web-dev-qa-db-ja.com

Python 3で例外を文字列に変換する

誰もアイデアを持っていますか、なぜこれPython 3.2コード

try:    
    raise Exception('X')
except Exception as e:
    print("Error {0}".format(str(e)))

問題なく動作します(WindowsシェルでのUnicodeエンコーディングは別です:/)が、

try:    
    raise Exception('X')
except Exception as e:
    print("Error {0}".format(str(e, encoding = 'utf-8')))

throws TypeError:strに強制:バイト、bytearrayまたはバッファのようなオブジェクトが必要、例外が見つかりました

カスタムエンコーディングでエラーを文字列に変換する方法は?

編集

メッセージに\ u2019が含まれる場合も機能しません。

try:    
    raise Exception(msg)
except Exception as e:
    b = bytes(str(e), encoding = 'utf-8')
    print("Error {0}".format(str(b, encoding = 'utf-8')))

しかし、なぜstr()は内部的に例外をバイトに変換できないのですか?

43
ts.

Python 3.x、str(e)は、Unicode文字が含まれている場合でも、Exceptionを文字列に変換できる必要があります。

したがって、例外がカスタム__str__()メソッドでUTF-8エンコードされたバイト配列を実際に返さない限り、str(e, 'utf-8')は期待どおりに動作しません(=で16ビットUnicode文字列を解釈しようとします) RAM UTF-8エンコードされたバイト配列として...)

私の推測では、あなたの問題はstr()ではなく、print()(つまり、Python Unicode文字列をダンプするものに変換するステップ)解決策については、この回答を参照してください: Python、Unicode、およびWindowsコンソール

44
Aaron Digulla

これを試してください、それは動作するはずです。

try:    
    raise Exception('X')
except Exception as e:
    print("Error {0}".format(str(e.args[0])).encode("utf-8"))

内部Tupleにはメッセージのみがあると考えてください。

10

Python3では、stringにはエンコードなどの属性がありません。内部的には常にUnicodeです。エンコードされた文字列には、バイト配列があります。

s = "Error {0}".format(str(e)) # string
utf8str = s.encode("utf-8") # byte array, representing utf8-encoded text
4
hamstergene

Python 3では、すでに「Unicodeスペース」にいるため、エンコードは必要ありません。達成したい内容によっては、変換を実行する前にすぐに行う必要があります。

例えば。あなたはこれをすべてbytes()に変換できますが、むしろ方向に

bytes("Error {0}".format(str(e)), encoding='utf-8')

3
glglgl

ここにバージョンに依存しない変換があります:

# from the `six` library
import sys
PY2 = sys.version_info[0] == 2
if PY2:
    text_type = unicode
    binary_type = str
else:
    text_type = str
    binary_type = bytes

def exc2str(e):
    if e.args and isinstance(e.args[0], binary_type):
        return e.args[0].decode('utf-8')
    return text_type(e)

そしてそれのためのテスト:

def test_exc2str():
    a = u"\u0856"
    try:
        raise ValueError(a)
    except ValueError as e:
        assert exc2str(e) == a
        assert isinstance(exc2str(e), text_type)
    try:
        raise ValueError(a.encode('utf-8'))
    except ValueError as e:
        assert exc2str(e) == a
        assert isinstance(exc2str(e), text_type)
    try:
        raise ValueError()
    except ValueError as e:
        assert exc2str(e) == ''
        assert isinstance(exc2str(e), text_type)
1
tsionyx