Discord.py调用Order类后代码终止运行问题排查
我的问题场景
我尝试用discord.py写一个订单机器人,主程序和对应的类代码如下:
主程序代码:
import discord import os from discord.ext import commands, tasks import classes.orders client = commands.Bot(command_prefix = '~') def read_token(): with open(r"D:\\documents\\discord bots\\discord bot py\\order bot\\order bot\\order-bot\\token.txt","r") as f: lines = f.readlines() return lines[0].strip() @client.command() async def ping(ctx): await ctx.send(f'Pong! {round(client.latency*1000)}ms') @client.command() async def order(ctx,element,number): member=ctx.author member = str(member) await ctx.send('order has been placed') print(f'ran {member}') new_order=Order(element,number) await ctx.send('order has been placed') number=newOrder.number for filename in os.listdir(r'D:\\documents\\discord bots\\discord bot py\\order bot\\order bot\\order-bot\\cogs'): if filename.endswith('.py'): client.load_extension(f'cogs.{filename[:-3]}') token=read_token() client.run(token)
classes/orders.py文件内容:
class Order: def _init_(self,element,number): print('ran') self.element=element self.number=number print('ran')
调用~order命令时,机器人会发送第一条order has been placed消息,控制台也能成功打印ran {member},但Order类里的构造函数代码完全没执行,创建实例后的后续代码(比如第二条order has been placed消息)也没运行,而且全程没有任何报错,其他命令比如ping都能正常使用。这到底哪里出问题了?
问题根源与解决方案
嘿,这是Python类里一个超级容易踩的小坑,我帮你揪出来了!
1. 构造函数名称写错了(核心问题)
在Python中,类的构造函数必须是双下划线开头+双下划线结尾的__init__,而你写的是单下划线的_init_。这种情况下,Python根本不会把这个方法当成构造函数,所以当你执行new_order=Order(element,number)时,并不会调用你写的_init_方法,而是用Python默认的无参构造函数。
那为什么没报错呢?因为你给Order实例化传了两个参数,默认构造函数不接受参数,其实已经抛出了TypeError异常,但discord.py的@client.command()装饰器默认会捕获异常并不显示——这就是你看不到报错的原因!
2. 变量名大小写不一致(次要问题)
主程序里还有个小错误:你实例化的对象是new_order(下划线小写),但后面写的是newOrder.number(驼峰式大写),这会导致后续代码抛出NameError,也得一起改。
具体修复步骤:
- 修改
orders.py中的构造函数名称,把_init_改成__init__:
class Order: def __init__(self,element,number): # 这里改成双下划线 print('ran') self.element=element self.number=number print('ran')
- 修改主程序中变量名的大小写问题:
@client.command() async def order(ctx,element,number): member=ctx.author member = str(member) await ctx.send('order has been placed') print(f'ran {member}') new_order=Order(element,number) await ctx.send('order has been placed') number=new_order.number # 这里改成和实例一致的new_order
改完这两处,重新启动机器人,再调用~order命令,你就能看到控制台打印两次ran,机器人也会正常发送第二条消息啦!
内容的提问来源于stack exchange,提问作者nzwoodturner

