【问题标题】:python codecs can't encode to cp1252...but notepad++ can?python编解码器无法编码为cp1252 ...但是notepad ++可以吗?
【发布时间】:2020-07-17 07:32:32
【问题描述】:

我有一段非常简单的代码可以转换 csv....还请注意,我曾多次引用 notepad++,但我的标准 IDE 是 vs-code。

with codecs.open(filePath, "r", encoding = "UTF-8") as sourcefile:
    lines = sourcefile.read()

with codecs.open(filePath, 'w', encoding = 'cp1252') as targetfile:
    targetfile.write(lines)

现在我正在做的工作需要将特定文件编码为 windows-1252,并且据我所知 cp1252=windows-1252。现在,当我使用 notepad++ 中的 UI 功能进行转换时,这种转换工作正常,但是当我尝试使用 python 编解码器对该文件进行编码时,它会失败;

UnicodeEncodeError: 'charmap' codec can't encode character '\ufffd' in position 561488: character maps to <undefined>

当我看到这个失败时,我很困惑,所以我仔细检查了当我使用 notepad++ 手动转换文件时的输出,并且转换后的文件是在 windows-1252 中编码的.....那么给出了什么?为什么 notepad++ 中的 UI 功能可以完成这项工作,但编解码器似乎无法完成这项工作? notepad++ 会忽略错误吗?

【问题讨论】:

    标签: python codec


    【解决方案1】:

    看起来您的输入文本包含字符“�”(实际占位符“替换字符”字符,而不是其他未定义字符),无法映射到 cp1252(因为它没有概念)。

    根据您的需要,您可以:

    • 在将lines 写入输出文件之前,在 Python 中将其过滤掉(或替换它,或以其他方式处理)。
    • errors=... 传递给第二个codecs.open,选择其他错误处理模式之一;默认为'strict',你也可以使用'ignore'、'replace'、'xmlcharrefreplace'、'backslashreplace'或'namereplace'。
    • 检查输入文件,看看为什么它有“�”字符;是否已损坏?

    【讨论】:

      【解决方案2】:

      可能 Python 在错误处理方面更加明确。如果 Notepad++ 能够正确地表示 CP-1252 中的每个字符,那么 Python 编解码器中存在一个错误,它不应该在当前失败的地方失败;但我猜记事本++正在默默地用其他一些字符替换一些字符,并错误地声称成功。

      如果数据不容易手动检查,可以尝试将结果转换回 UTF-8 并逐字节比较文件。

      Uncode U+FFFD 是一个保留字符,用作无法用 Unicode 表示的字符的占位符;通常,这表明之前存在转换问题,可能是该数据在较早的时间点输入不完善或转换。

      (是的,Windows-1252 是 Windows 代码页 1252 的另一个名称。)

      【讨论】:

        【解决方案3】:

        为什么记事本++“成功”

        Notepad++ 不提供您将文件转换cp1252,而是使用此编码重新解释它。导致您感到困惑的是,他们实际上使用了错误的术语。这是程序中的编码菜单:

        When "Encode with cp1252" is selected, Notepad decodes the file using cp1252 and shows you the result.如果将字符 '\ufffd' 保存到使用 utf8 的文件中:

        with open('f.txt', 'w', encoding='utf8') as f:
            f.write('\ufffd')`
        

        并使用“使用 cp1252 编码”,您会看到三个字符:

        这意味着 Notepad++ 不会读取utf8 中的字符,然后将其写入cp1252,因为那样您只会看到一个字符。您可以通过使用cp1252 读取文件来获得与 Notepad++ 类似的结果:

        with open('f.txt', 'r', encoding='cp1252') as f:
            print(f.read()) # Prints �
        

        Notepad++ 实际上只允许您转换为五种编码,如您在上面的屏幕截图中所见。

        你应该怎么做

        cp1252 编码中不存在此字符,这意味着您无法在不丢失信息的情况下转换此文件。常见的解决方案是跳过此类字符或将它们替换为您的编码中存在的其他类似字符(请参阅encoding error handlers

        【讨论】:

          【解决方案4】:

          您正在处理"utf-8-sig" 编码——请将此编码指定为encoding 参数,而不是"utf-8"

          上面有信息in the docs(搜索页面“utf-8-sig”)。

          为了提高检测 UTF-8 编码的可靠性,Microsoft 为其记事本程序发明了 UTF-8 的变体(Python 2.5 调用 "utf-8-sig"):在将任何 Unicode 字符写入文件,写入一个 UTF-8 编码的 BOM(看起来像这样的字节序列:0xef、0xbb、0xbf)。 [...]

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-12-24
            • 2021-06-14
            • 2010-12-22
            • 1970-01-01
            • 2017-03-01
            • 1970-01-01
            • 2014-06-23
            • 1970-01-01
            相关资源
            最近更新 更多