【问题标题】:Python2: Using .decode with errors='replace' still returns errorsPython2:使用带有errors='replace'的.decode仍然返回错误
【发布时间】:2017-02-23 01:13:15
【问题描述】:

所以我有一个message,它是从一个未知编码的文件中读取的。我想发送到网页进行显示。我对 UnicodeErrors 做了很多努力,并且在 StackOverflow 上经历了许多问答,我认为我对 Unicode 和编码的工作原理有很好的理解。我当前的代码是这样的

try :
            return message.decode(encoding='utf-8')
        except:
            try:
                return message.decode(encoding='latin-1')
            except:
                try:
                    print("Unable to entirely decode in latin or utf-8, will replace error characters with '?'")
                    return message.decode(encoding='utf-8', errors="replace")

然后将返回的消息转储为 JSON 并发送到前端。

我假设因为我在最后一个 try except 上使用了 errors="replace",所以我会以牺牲一些“?”为代价来避免异常。我的显示中的字符。可接受的成本。

但是,我似乎太抱有希望了,对于某些文件,我仍然收到UnicodeDecodeException 说“ascii 编解码器无法解码”某些字符。为什么errors="replace" 不解决这个问题?

(也是一个额外的问题,ascii 与这些有什么关系?.. 我指定的是 UTF-8)

【问题讨论】:

  • 您能粘贴一个消息示例吗? SO 小部件忠实于 unicode 和其他奇怪的东西,因此它将成为真正的 minimal reproducible example
  • 哪一行代码你得到了UnicodeDecodeException
  • 这是引发错误的最后一行。稍后我会更新异常跟踪。
  • 如果对问题所在感到好奇,请查看我对@bobince 的回答的评论

标签: python python-2.7 unicode character-encoding


【解决方案1】:

你不应该得到UnicodeDecodeErrorerrors='replace'str.decode('latin-1') 也永远不会失败,因为 ISO-8859-1 对每个可能的字节序列都有一个有效的字符映射。

我怀疑message 已经是unicode 字符串,而不是字节。 Unicode 文本已从字节中“解码”,无法再解码。

当您调用 .decode()unicode 字符串时,Python 2 会尝试提供帮助并决定将 Unicode 字符串编码回字节(使用默认编码),这样您就有你可以真正解码的东西。此隐式编码步骤使用errors='replace',因此如果Unicode 字符串中有任何字符不是默认编码(可能是ASCII),您将获得Unicode<strong>En</strong>codeError

(Python 3 不再这样做,因为它非常令人困惑。)

检查message 的类型并假设它确实是Unicode,从那里返回以找到它被解码(可能是隐式)的位置,以用正确的解码替换它。

【讨论】:

  • 所以你是对的,这似乎是正在发生的事情。我曾尝试使用 encode('latin-1') 或 decode('latin-1') ,每个都在某些时候给我错误。我刚刚意识到问题在于传入的字符串不一致。有时它是 unicode,有时它是编码的。因此,如果我使用这两种方法中的任何一种,我会得到UnicodeEncodeErrorUnicodeDecodeError,具体取决于哪个失败。我通过尝试解码然后在失败时尝试编码来修复它,它似乎有效。至少在我找到不一致输入的来源之前。
  • 官方文档总是有助于完成图片并帮助我理解事物。这是bytes.decode()docs.python.org/3/library/stdtypes.html#bytes.decode。对于errors=replace 参数:docs.python.org/3/library/codecs.html#error-handlers
【解决方案2】:

decode with error replace 实现了'replace'错误处理(仅适用于文本编码):替换'?'用于编码错误(由编解码器编码),'\ufffd'(Unicode 替换字符)用于解码错误

文本编码是指“将 Unicode 字符串编码为字节的编解码器”。

也许您的数据格式错误 - 您应该尝试“忽略”错误处理,其中忽略格式错误的数据并继续编码或解码,恕不另行通知。

message.decode(encoding='utf-8', errors="ignore")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多