在 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。 @SebastianoMerlinoargs[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 数组