【问题标题】:'UCS-2' not able to encode“UCS-2”无法编码
【发布时间】:2017-07-07 07:36:29
【问题描述】:

我正在尝试读取文本文件,但它引发了一个错误。

UnicodeEncodeError: 'UCS-2' codec can't encode characters in position 12416-12416: Non-BMP character not supported in Tk

我也试图忽略它,但我没有工作。 代码如下:

with io.open('reviews1.txt', mode='r',encoding='utf-8') as myfile:
document1=myfile.read().replace('\n', '')
print(document1)

【问题讨论】:

  • 试试surrogateescape error handler?尽管如此,请edit您的问题并显示完整的回溯。
  • 问题不在于读取文件(这将是一个de编码错误)。它与print 表达式有关:您的环境显然无法处理BMP 之外的字符,例如表情符号。写入文件是一种选择吗?
  • 我可以在 Python 3.5 IDLE 环境中重现该错误。但是,脚本可以从控制台顺利运行(在我的例子中是 Windows cmd)。 @lenz 是对的,错误与print 有关。
  • 是的,但是如何克服呢? @JosefZ
  • 我已经先将数据保存到同一个文件中。现在我正在尝试读取和打印该文件的数据。无论如何,我们可以在写作或阅读时删除该字符吗? @lenz

标签: python-3.x utf-8


【解决方案1】:

问题不在于读取文件(这将是一个de编码错误)。 它与打印表达式有关:您的环境显然无法处理 BMP 之外的字符,例如表情符号。

如果您想将这些字符打印到 STDOUT,您可以检查您的 shell/IDE 是否支持支持所有 Unicode(UTF-8、UTF-16...)的编码。 或者您切换到不同的环境来运行脚本。

如果您想在相同的设置中运行它,您可以自己对数据进行编码,这样您就可以选择指定自定义错误处理:

data = document1.encode('UCS-2', errors='replace')
sys.stdout.buffer.write(data)

这会将不受支持的字符替换为? 或其他字符。 您还可以指定errors='ignore',这将抑制字符。

不过,我无法对此进行测试,因为我的编解码器库不知道 UCS-2 编码。在 NT 之前,它是 Windows 使用的过时标准。

【讨论】:

    【解决方案2】:

    我可以在Python IDLE environment (Python version 3.5.1, Tk version 8.6.4, IDLE version 3.5.1) 中重现错误。这似乎是Tk 中的一个错误。但是,原始脚本可以从控制台顺利运行(在我的情况下是 Windows cmd):Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32

    我能看到的唯一方法可能是非常慢:以下注释脚本逐个字符地复制整个文档,消除了Basic Multilingual Plane中的所有字符。

    编辑:我找到了this (more Python-ish) solution (thanks to Mark Ransom)。不幸的是,这在 Python shell 中运行,但 Python 控制台抱怨:

    >>> print( ''.join(c if c <= '\uffff' else ''.join(chr(x) for x in struct.unpack(
    ...   '>2H', c.encode('utf-16be'))) for c in document1)
    ... )
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
      File "C:\Python\Python35\lib\site-packages\win_unicode_console\streams.py",
    line 179, in write
    
        return self.base.write(s)
    UnicodeEncodeError: 'utf-16-le' codec can't encode character '\ud83d' in position 0: 
    surrogates not allowed
    >>>
    

    -

    # -*- coding: utf-8 -*-
    
    import sys, io
    import os, codecs                       # for debugging
    
    print(os.path.basename(sys.executable), sys.argv[0], '\n') # for debugging
    
    #######################
    ### original answer ###
    #######################
    filepath = 'D:\\test\\reviews1.txt'
    with io.open(filepath, mode='r',encoding='utf-8') as myfile:
        document1=myfile.read() #.replace('\n', '')
        document2=u''
        for character in document1:
            ordchar = ord(character)
            if ordchar <= 0xFFFF:
                # debugging # print( 'U+%.4X' % ordchar, character)
                document2+=character
            else:
                # debugging # print( 'U+%.6X' % ordchar, '�')
                ###         �=Replacement Character; codepoint=U+FFFD; utf8=0xEFBFBD
                document2+='�'
    print(document2)                        # original answer, runs universally
    
    ######################
    ### updated answer ###
    ######################
    if os.path.basename(sys.executable) == 'pythonw.exe':    
        import struct
        document3 = ''.join(c if c <= '\uffff' else ''.join(chr(x) for x in struct.unpack('>2H', c.encode('utf-16be'))) for c in document1)
        print(document3)                    # Pythonw shell
    else:
        print(document1)                    # Python console
    

    输出,Pythonw shell:

    ================== RESTART: D:/test/Python/Py/q44965129a.py ==================
    pythonw.exe D:/test/Python/Py/q44965129a.py 
    
    � smiling face with smiling eyes �
    � smiling face with open mouth   �
    � angry face                     �
    
    ? smiling face with smiling eyes ?
    ? smiling face with open mouth   ?
    ? angry face                     ?
    
    >>>
    

    输出,Python 控制台:

    ==> D:\test\Python\Py\q44965129a.py
    python.exe D:\test\Python\Py\q44965129a.py
    
    � smiling face with smiling eyes �
    � smiling face with open mouth   �
    � angry face                     �
    
    ? smiling face with smiling eyes ?
    ? smiling face with open mouth   ?
    ? angry face                     ?
    
    ==>
    

    【讨论】:

    • 为什么使用io.open 而内置open 也一样?当str.encode 提供errors='replace' 模式时,为什么要通过手动检查逐字符进行迭代,而这正是为您做的?不要重新发明轮子......
    • @lenz 1。我知道io.open is an alias for the builtin open() function。这是 OP 的设计……2。您是否尝试应用 any 错误处理程序?显然,您没有:您无法对此进行测试 (sic!)
    • 哦,我没看到你从 OP 那里拿走了io.open - 很抱歉因此而责备你。关于测试:是的,很遗憾。根据 OP 的错误消息,必须有一个具有UCS-2 编解码器的 Python 版本/实现;也许它仅在 Windows 上可用。你能执行我的建议吗?
    猜你喜欢
    • 1970-01-01
    • 2018-01-24
    • 2015-12-03
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    相关资源
    最近更新 更多