UnicodeEncodeError:“UCS-2”编解码器无法对位置 8-8 中的字符进行编码:Tk 中不支持非 BMP 字符 [重复]

Posted

技术标签:

【中文标题】UnicodeEncodeError:“UCS-2”编解码器无法对位置 8-8 中的字符进行编码:Tk 中不支持非 BMP 字符 [重复]【英文标题】:UnicodeEncodeError: 'UCS-2' codec can't encode characters in position 8-8: Non-BMP character not supported in Tk [duplicate] 【发布时间】:2018-12-12 05:50:51 【问题描述】:

请记住,我今天刚开始使用 Python,所以我很糟糕。

您好,我正在为 Discord 编写一个机器人,但我在运行它时遇到了问题。我正在尝试使其在线,但我遇到了同样的错误。我不知道错误来自哪里。有人可以帮忙吗?

到目前为止,这是我的代码:

import discord

from discord.ext.commands import bot

from discord.ext import commands

import asyncio

import time

Client = discord.Client()

client = commands.Bot(command_prefix = "~")

@client.event
async def on_ready():

    print("I'm up on some BOOF!" + client.user.id)
    print("I am the" + client.user.name)

@client.event
async def on_message(message):

    if message.content == "Boof":
        await client.send_message(message.channel, ":b:")


client.run("<redacted>")

我得到的错误:

Ignoring exception in on_ready
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/discord/client.py", line 307, in _run_event
    yield from getattr(self, event)(*args, **kwargs)
  File "/Users/johnathanhelsel/Documents/Boof Bot/BoofBot.py", line 13, in on_ready
    print("I am the" + client.user.name)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/idlelib/run.py", line 362, in write
    return self.shell.write(s, self.tags)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/idlelib/rpc.py", line 604, in __call__
    value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/idlelib/rpc.py", line 216, in remotecall
    return self.asyncreturn(seq)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/idlelib/rpc.py", line 247, in asyncreturn
    return self.decoderesponse(response)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/idlelib/rpc.py", line 267, in decoderesponse
    raise what
UnicodeEncodeError: 'UCS-2' codec can't encode characters in position 8-8: Non-BMP character not supported in Tk

我完全被困住了!我已经尝试了所有发布的解决方案,但没有任何效果。可以的话请帮忙!

PS,我已经换过token了,别试了。

谢谢-乔纳森

【问题讨论】:

【参考方案1】:

您的代码可能没有问题,而是 IDLE 有问题。如果您从控制台或其他 IDE(如 PyCharm 或 Spyder)运行相同的代码,它会正常工作。

从 3.7 开始,IDLE 在内部将所有字符串处理为 UCS-2,这是一种过时的编码,只能处理 Unicode 中的前 65536 个字符。1

那么,当你尝试向它传递一个具有“星体字符”的字符串时会发生什么,一个超出该范围的字符?嗯,这取决于各种细节,但通常是UnicodeEncodeError 像这样的。

这意味着,如果您的客户的姓名包括补充 CJK 范围中的字符(许多中文姓氏都有)或表情符号,则此行将引发该异常:

print("I am the" + client.user.name)

…因为 IDLE 尝试获取 print 输出并将其转换为在 tkinter 输出上显示。


要解决此问题,您需要在打印之前明确删除或替换任何星体字符:

def clean_remove(s):
    return ''.join(c for c in s if ord(c) < 65536)
def clean_replace_question(s):
    return ''.join(c if ord(c) < 65536 else '?' for c in s)
def clean_replace_unicode(s):
    return ''.join(c if ord(c) < 65536 else '\ufffd' for c in s)
print("I am the" + clean_whichever(client.user.name))

您可以更高效地编写它,但这不太重要(无论如何,在 tkinter 窗口中显示文本要慢得多),希望这种方式易于理解。

您还可以使用自定义 print 函数在传递给内置函数之前执行此过滤,或者使用自定义替换 sys.stdout 为您过滤内容。

或者你不能在 IDLE 中运行你的代码。


1。 UCS-2 已被 UTF-16 取代,事实上很多年前,但只有有人可以修复与每个受支持的 GUI 平台(主要是 Windows)和每个受支持的 Tcl/Tk 版本的字符串处理代码接口,才能更新 IDLE ,这还没有发生。

【讨论】:

它回来了:NameError: name 'clean_whichever' is not defined @JohnathanHelsel:那是因为它是上面定义的三个替代函数中的任何一个的占位符 - 选择一个最适合您的目的。 我在这方面真的很糟糕,所以我不知道。我什至让我知道 python 的朋友尝试提供帮助,但他不知道您的意思。【参考方案2】:

您的问题是您试图在 IDLE 编辑器中运行您的代码。 IDLE 编辑器使用 UCS-2 编码,因此当您尝试使用奇怪的 unicode 字符和表情符号打印用户名字符串时,IDLE 窗口无法显示它。

我建议使用字符串的ascii() 进行调试,这将打印 unicode 的 python 表示而不是实际的代码点(根据目标窗口无法打印):

print(ascii("I am the" + client.user.name))

【讨论】:

Ubuntu 18.04 提供的 Python 3.6 中的 IDLE 窗口在显示 repr() 时会产生相同的错误,因为 repr() 没有转义非 BMP 字符。 @DamianYerrick repr() 的字符串将始终被转义 - 也许您在另一个对象上使用 repr(),然后这是该对象类中的错误。理想情况下,__repr__ 不应返回 nonascii。 在 Debian 10 上的 Python 3.7.3 中,print(repr('?')) 返回 '?' 嗯,看起来获得纯 ascii 表示的新方法现在是 ascii() 内置函数:print(ascii('?')) 返回 '\U0001f426' docs.python.org/3/library/functions.html#ascii @DamianYerrick 我已相应地编辑了答案,谢谢为此

以上是关于UnicodeEncodeError:“UCS-2”编解码器无法对位置 8-8 中的字符进行编码:Tk 中不支持非 BMP 字符 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

UCS-2/UCS-4/UTF

Python編碼格式錯誤解決方案及案例

UCS-2 和 SQL Server

细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4

细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4

细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4