在 Python 3 中将异常转换为字符串

Posted

技术标签:

【中文标题】在 Python 3 中将异常转换为字符串【英文标题】:Converting Exception to a string in Python 3 【发布时间】:2011-10-27 20:38:48 【问题描述】:

有谁知道为什么这个 Python 3.2 代码

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

工作没有问题(除了 windows shell 中的 unicode 编码:/), 但是这个

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

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

如何将错误转换为自定义编码的字符串?

编辑

如果消息中有\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() 不能在内部将异常转换为字节?

【问题讨论】:

你试过str(e).encode('utf-8')吗? @agf 它本身返回字节而不是字符串。我可以用它来替换字节(str(e),编码='utf-8'),但我总是要做第二次转换字节=> str “为什么 str() 不能转换为字节”——它怎么知道要转换成哪种编码?此外,您的新代码相当于 .format(str(e)) @Eugene 是对的。您应该在格式化后对其进行编码。如果您尝试使用 encoding 参数,则它要求源可作为字节访问。 @Eugene 尝试在法文win7的windows shell中运行,你会发现不等价 【参考方案1】:

这里有一个版本无关的转换:

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

【讨论】:

【参考方案2】:

试试这个,应该可以的。

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

考虑到您的内部元组中只有一条消息。

【讨论】:

这是我尝试的第一件事,唉:AttributeError: 'Exception' object has no attribute 'message' 哦,你是对的;这是因为在 > 3 版本中,python 使用 args 而不是 message。 @SebastianoMerlino args[0] 在 Python 2.7 和 Python 3.5 中工作吗?您是否有任何源/文档为什么它被删除? @matth 我发现args[0] 也适用于 Python 2.7。【参考方案3】:

在 Python 3 中,您已经在“unicode 空间”中,不需要编码。根据您想要实现的目标,您应该在执行操作之前立即进行转换。

例如您可以将所有这些都转换为bytes(),而是在方向上

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

.

【讨论】:

【参考方案4】:

在 Python 3.x 中,str(e) 应该能够将任何 Exception 转换为字符串,即使它包含 Unicode 字符。

因此,除非您的异常实际上在其自定义 __str__() 方法中返回 UTF-8 编码字节数组,否则 str(e, 'utf-8') 将无法按预期工作(它会尝试将 RAM 中的 16 位 Unicode 字符串解释为 UTF-8编码字节数组...)

我的猜测是您的问题不是str(),而是print()(即将 Python Unicode 字符串转换为在您的控制台上转储的内容的步骤)。请参阅此答案以获取解决方案:Python, Unicode, and the Windows console

【讨论】:

确实,最初我遇到了 UnicodeEncodeError: 'charmap' codec can't encode character... 在法文版 Win 7 下的 shell 中的问题。它似乎更便携将所有内容显式转换为 utf-8,而不是使用一些自定义的、依赖于操作系统的包装器。【参考方案5】:

在 Python3 中,string 没有编码这样的属性。它在内部始终是 unicode。对于编码字符串,有字节数组:

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

【讨论】:

它只是构造函数的一个参数,它会导致它使用这种编码将字节数组解码为unicode。 所以我不明白你的反应。你能详细说明一下吗?

以上是关于在 Python 3 中将异常转换为字符串的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 3 中将字节转换为十六进制字符串的正确方法是啥?

在 Python 3 中将字符串转换为 int 或 float?

在 Python 3 中将逗号分隔的字符串转换为 Numpy 数组

在 Python 3.9.6 中将 b 字符串转换为 png

在 Python 3 中将二进制字符串转换为字节数组

在Python 3中将十六进制字符串(python 2)转换为带有十六进制数字的字节