【问题标题】:Converting Exception to a string in Python 3在 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中运行,你会发现不等价

标签: python exception unicode character-encoding


【解决方案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。
      • 所以我不明白你的反应。你能详细说明一下吗?
      猜你喜欢
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      相关资源
      最近更新 更多