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

Discord机器人接收数字消息输入触发TypeError报错的问题咨询

报错触发原因定位
  • 函数与变量重名覆盖:原本设计中alg是承担面积计算功能的自定义函数,但代码执行过程中,某段逻辑将字符串类型的内容赋值给了同名变量alg,原本的函数引用已被字符串完全覆盖。执行到alg(int(message.content()))这行时,本质是拿着字符串当可调用对象使用,必然抛出TypeError: 'str' object is not callable错误。就算没有重名问题,代码也没有接收函数调用的返回值,直接把函数本身作为参数传给channel.send,最终频道里发出来的内容会是函数对象的内存地址,根本不是计算结果。
  • 框架语法使用错误:原代码里message.content()的写法不符合Discord.py的框架规则。message.content是存储消息文本的字符串属性,不是可执行的方法,不需要加括号调用,正确写法是去掉括号直接读取属性值。
  • 交互逻辑存在缺陷:当前代码没有设置输入状态标记,只要频道内出现任意用户发送的消息,就会直接走半径计算流程。既会把用户的闲聊内容当成半径输入,也没法实现“先发提示引导、等用户回复后再计算”的交互节奏,甚至会因为机器人自己发的提示消息触发on_message事件,造成逻辑死循环。
稳定运行的修正方案
  • 给自定义计算函数更换一个不会和其他变量重名的命名(比如命名为calc_circle_area),从根源上避免函数引用被后续的字符串变量覆盖。
  • 增加频道级状态标记,用字典记录每个频道当前是否处于“等待用户输入半径”的状态,只有状态匹配时才会解析计算逻辑,避免误触发。
  • 增加输入合法性校验,用户发送的内容不是有效整数时,直接返回提示要求重新输入,不要强行做类型转换导致程序崩溃。
  • 增加机器人自身消息的过滤规则,拦截机器人账号发送的消息触发的on_message事件,切断逻辑循环。

可运行的参考实现:

# 频道输入状态存储字典,key为频道ID,value为当前等待的输入类型
channel_wait_state = {}

# 自定义计算函数,与其他变量无重名
def calc_circle_area(radius: int) -> float:
    if radius < 0:
        raise ValueError("半径不能为负数")
    return 3.14159 * radius * radius

@client.event
async def on_message(message):
    # 过滤机器人自身发送的消息,避免触发死循环
    if message.author.bot:
        return

    # 匹配用户触发计算的指令
    if message.content.strip() == "计算圆面积":
        channel_wait_state[message.channel.id] = "waiting_for_radius"
        await message.channel.send("请输入圆的半径(整数形式)")
        return

    # 匹配等待半径输入的频道状态
    if channel_wait_state.get(message.channel.id) == "waiting_for_radius":
        # 收到有效输入后立刻重置状态,避免重复触发
        del channel_wait_state[message.channel.id]
        # 校验输入合法性
        input_text = message.content.strip()
        if not input_text.lstrip('-').isdigit():
            await message.channel.send("输入无效,请发送整数形式的半径值")
            return
        radius = int(input_text)
        try:
            area = calc_circle_area(radius)
        except ValueError as e:
            await message.channel.send(f"输入无效:{e}")
            return
        await message.channel.send(f"半径为{radius}的圆,面积计算结果为:{area:.2f}")
        return

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 20:06:05