Converting Exception to a string in Python 3

百般思念 提交于 2020-07-31 15:00:47

问题


does anyone have an idea, why this Python 3.2 code

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

works without problem (apart of unicode encoding in windows shell :/), but this

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

throws TypeError: coercing to str: need bytes, bytearray or buffer-like object, Exception found ?

How to convert an Error to a string with custom encoding?

Edit

It does not works either, if there is \u2019 in message:

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

But why cannot str() convert an exception internally to bytes?


回答1:


In Python 3.x, str(e) should be able to convert any Exception to a string, even if it contains Unicode characters.

So unless your exception actually returns an UTF-8 encoded byte array in its custom __str__() method, str(e, 'utf-8') will not work as expected (it would try to interpret a 16bit Unicode character string in RAM as an UTF-8 encoded byte array ...)

My guess is that your problem isn't str() but the print() (i.e. the step which converts the Python Unicode string into something that gets dumped on your console). See this answer for solutions: Python, Unicode, and the Windows console




回答2:


Try this, it should work.

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

Considering you have only a message in your internal tuple.




回答3:


In Python3, string does not have such attribute as encoding. It's always unicode internally. For encoded strings, there are byte arrays:

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



回答4:


In Python 3, you are already in "unicode space" and don't need encoding. Depending on what you want to achieve, you should the conversion do immediately before doing stuff.

E.g. you can convert all this to bytes(), but rather in the direction

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

.




回答5:


There is a version-agnostic conversion here:

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

and tests for it:

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)


来源:https://stackoverflow.com/questions/7075200/converting-exception-to-a-string-in-python-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!