请记住,我今天才刚开始使用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,我已经更改了令牌,甚至都不要尝试。
谢谢约翰娜(Johnathan)
答案 0 :(得分:1)
您的代码可能没有问题,但是IDLE有问题。如果您从控制台运行相同的代码,或者从不同的IDE(例如PyCharm或Spyder)运行该代码,就可以正常工作。
从3.7开始,IDLE在内部将所有字符串作为UCS-2处理,这是一种过时的编码,只能处理Unicode中的前65536个字符。 1
那么,当您尝试向其传递具有“星形字符”(超出此范围的字符)的字符串时会发生什么?嗯,这取决于各种细节,但通常是这样的UnicodeEncodeError
。
这意味着如果您的客户的名字包括来自补充CJK范围的字符(许多中文姓氏都包含该字符)或Emoji,则此行将引发该异常:
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
函数对Python进行猴子补丁,该函数在传递到内置函数之前进行此过滤,或者使用sys.stdout
的自定义替代函数为您过滤内容。
否则,您将无法在IDLE中运行代码。
1。实际上,UCS-2已由UTF-16取代,实际上早在很多年前,但是只有在有人可以修复与每个受支持的GUI平台(主要是Windows)和每个受支持的Tcl /连接的字符串处理代码之前,IDLE才能更新。 Tk版本,尚未发生。
答案 1 :(得分:0)
您的问题是您试图在IDLE编辑器中运行代码。 IDLE编辑器使用UCS-2编码,因此当您尝试使用奇怪的Unicode字符和表情符号打印用户名字符串时,IDLE窗口将无法显示它。
我建议使用字符串的repr()
进行调试,这将打印unicode的python表示形式,而不是实际的代码点(根据目标窗口无法打印):
print(repr("I am the" + client.user.name))