【问题标题】:Convert exception to string in Python 2.7在 Python 2.7 中将异常转换为字符串
【发布时间】:2015-11-30 13:54:01
【问题描述】:
import httplib

webservice = httplib.HTTPSConnection(host)
# ....
try:
    webservice.endheaders()
except Exception, exc:
    handle_failure(request, exc_str=unicode(exc))

异常包含:

错误(110,'Die Wartezeit f\xc3\xbcr die Verbindung ist abgelaufen')

不要问我为什么这条消息是德语的。

uncode(exc) 失败如下:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 27:
                     ordinal not in range(128)

在 Python 2.7 中将异常转换为字符串的故障安全方法是什么?

在这种情况下故障安全的定义:我不能得到 UnicodeError。期望进入日志。非ascii字符丢失也没关系。

【问题讨论】:

  • 您有什么理由必须使用unicode 而不能只使用exc_str=str(exc)
  • 尝试使用str(exc)简单地将异常类型转换为str
  • 如果你想要一个 unicode 字符串,你会.decode,看起来你已经有了一个 utf-8 编码的字符串,所以不知道为什么要更改它。使用unicode(s) 将尝试使用ascii 编码,您将使用unicode(s,"utf-8"),如前所述解码或直接使用字符串

标签: python python-2.7 exception python-unicode


【解决方案1】:

errors='replace'errors='ignore' 参数添加到unicode 函数。

以下文字来自this文档:

errors 参数指定输入字符串不能时的响应 根据编码规则进行转换。为此的法律价值 参数是“严格的”(引发UnicodeDecodeError 异常), ‘replace’(添加 U+FFFD、‘REPLACEMENT CHARACTER’)或 ‘ignore’(只需 将字符排除在 Unicode 结果之外)。以下示例 显示差异:

$ unicode('\x80abc', errors='strict')     
Traceback (most recent call last):
...
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
ordinal not in range(128)
$ unicode('\x80abc', errors='replace')
u'\ufffdabc'
$ unicode('\x80abc', errors='ignore')
u'abc'

【讨论】:

  • @PadraicCunningham OP 确实要求采用故障安全方式,如果他们不知道编码,那么这样做可能更安全。但是 mgn 可能应该注意到这会导致数据丢失。
  • @PadraicCunningham 我更新了问题。在这种情况下故障安全的定义:我不能得到 UnicodeError。期望进入日志。非ascii字符丢失也没关系。
  • @guettli,你为什么要使用 unicode?你不知道编码是什么吗?
  • @PadraicCunningham 为什么我使用unicode(exc)?因为我想将字符串写入文件。我知道我想要创建的输出的编码。但我不知道异常中的垃圾。异常不是来自我的代码。
  • @guettli,你看到的是一个 utf-8 编码的字符串,如果数据来自同一个源,它很可能都是 utf-8 编码的,你可以写入文件没问题,当您尝试使用 unicode 函数的默认值解码为 ascii 时,您只会看到错误
【解决方案2】:

unicodestr 转换采用默认 ASCII 编码。而且它们与 Python3 不兼容(现在可能不是问题,但以后会成为问题)。

我的建议是使用 decode 方法从 Python2 字符串生成 unicode 并使用 encode 从 unicode 生成 Python2 字符串。这当然使用您的本地编码,如果您希望它不受编码/解码错误的影响,可以选择添加errors = 'replace'

在这里,你应该写:

except Exception, exc:
    handle_failure(request, exc_str=exc.decode('utf8', errors='replace')

在我的系统上,以你的例子给出:Die Wartezeit für die Verbindung ist abgelaufen

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-27
    • 2018-03-07
    • 2016-01-01
    • 2017-03-30
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多