You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord多语言Bot加载含表情的.po/.mo文件触发UnicodeDecodeError

解决Discord Bot多语言表情导致的UnicodeDecodeError问题

问题根源

错误UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0...是因为gettext默认用ASCII编码加载翻译文件,而你的.po/.mo文件包含UTF-8编码的emoji(🏓是4字节UTF-8字符),超出了ASCII的编码范围。

解决方案

1. 确保.po文件保存为UTF-8编码

用文本编辑器打开.po文件,确认编码设置为UTF-8(无BOM)。比如VS Code右下角可查看和切换编码,保存时选择「UTF-8」即可。

2. 编译.mo文件时指定UTF-8编码

使用msgfmt编译.po文件时,显式指定编码参数,避免生成的.mo文件默认用ASCII编码:

msgfmt --encoding=utf-8 de.po -o locales/de/LC_MESSAGES/ping.mo

3. Python代码中显式设置gettext编码

加载翻译时,给gettext.translation()加上encoding='utf-8'参数,强制用UTF-8解码翻译内容:

trans = gettext.translation(
    domain="ping", localedir="locales", languages=[lang], fallback=True, encoding='utf-8'
)

4. 修正代码逻辑错误

原代码存在结构问题:__init__方法中直接访问interaction无效,interaction仅在命令执行时传入。正确逻辑应放在命令函数内:

import gettext
import json
from datetime import datetime

import discord
from discord import app_commands
from discord.ext import commands


class Ping(commands.Cog):
    def __init__(self, client: commands.Bot):
        self.client = client

    @app_commands.command(name="ping", description="查看机器人延迟")
    async def ping(self, interaction: discord.Interaction):
        # 加载服务器语言配置
        with open("data/languages.json", encoding="utf-8") as f:
            guild_languages = json.load(f)

        lang = guild_languages.get(str(interaction.guild.id), "en")
        # 加载翻译并指定UTF-8编码
        trans = gettext.translation(
            domain="ping", localedir="locales", languages=[lang], fallback=True, encoding='utf-8'
        )

        ping = round(self.client.latency * 1000)
        embed = discord.Embed(
            title=trans.gettext("PING_TITLE"),
            description=trans.gettext("PING_DESCRIPTION").format(ping=ping),
            color=0x1365EA,
            timestamp=datetime.now(),
        )
        embed.set_author(
            name=str(interaction.user), icon_url=interaction.user.avatar.url
        )
        await interaction.response.send_message(embed=embed)


async def setup(client):
    await client.add_cog(Ping(client))

验证

完成以上步骤后,重新编译.mo文件,启动Bot执行ping命令,emoji即可正常显示,不会再出现解码错误。

内容的提问来源于stack exchange,提问作者Navis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 13:03:36