Discord Bot开发:无法从discord导入Select的错误求助
Discord Bot 导入错误:无法从 'discord' 导入 'Select'
错误信息
Traceback (most recent call last): File "c:\Users\name\Desktop\Discord\main.py", line 4, in <module> from discord import Select, SelectOption, ActionRow ImportError: cannot import name 'Select' from 'discord'
问题背景
中断编程半年后,之前能正常运行的Discord Bot代码出现上述导入错误,尝试多种网络方法耗时2小时仍未解决,现寻求技术支持。完整代码如下:
import discord from discord.ext import commands from discord import Select, SelectOption, ActionRow intents = discord.Intents.default() intents.members = True intents.message_content = True bot = commands.Bot(command_prefix='!', intents=intents) intents.typing = False intents.presences = False users = {} @bot.event async def on_ready(): print(f'Вошел в систему как {bot.user}') @bot.command() async def start(ctx): user_id = ctx.author.id if user_id not in users: users[user_id] = { 'games': 0, 'currency': 0 } embed = discord.Embed( title="Успешная регистрация", description="Вы успешно зарегистрировались!", color=discord.Color.green() ) await ctx.send(embed=embed) else: embed = discord.Embed( title="Регистрация не удалась", description="Вы уже зарегистрированы!", color=discord.Color.red() ) await ctx.send(embed=embed) @bot.command() async def играть(ctx): options = [ SelectOption(label="Угадай число", value="option1"), SelectOption(label="Option 2", value="option2"), SelectOption(label="Option 3", value="option3"), ] select = Select(custom_id="select_menu", placeholder="Выберите опцию", options=options) action_row = ActionRow(select) await ctx.send("Пожалуйста, выберите опцию:", components=[action_row]) @bot.event async def on_select_option(interaction: discord.Interaction): if interaction.custom_id == "select_menu": selected_value = interaction.data["values"][0] await interaction.response.send_message(f"Вы выбрали: {selected_value}", ephemeral=True) @bot.command() @commands.has_role('Chapter [10]') async def money(ctx, action, user: discord.Member, amount: int): user_id = user.id if user_id in users: if action == 'выдать': users[user_id]['currency'] += amount await ctx.send(f'Вы выдали {amount} валюты пользователю {user.name}') elif action == 'забрать': if users[user_id]['currency'] >= amount: users[user_id]['currency'] -= amount await ctx.send(f'Вы забрали {amount} валюты у пользователя {user.name}') else: await ctx.send('У пользователя недостаточно валюты!') else: await ctx.send('Недопустимое действие!') else: await ctx.send('Пользователь не зарегистрирован!') @bot.command() async def info(ctx): user_id = ctx.author.id if user_id in users: games = users[user_id]['games'] currency = users[user_id]['currency'] registration_date = users[user_id]['registration_date'] embed = discord.Embed(title='Статистика', color=discord.Color.blue()) embed.add_field(name='Количество игр', value=games, inline=False) embed.add_field(name='Количество валюты', value=currency, inline=False) embed.add_field(name='Дата регистрации', value=registration_date, inline=False) await ctx.send(embed=embed) else: await ctx.send('Вы не зарегистрированы!') bot.run('TOKEN')
解决方案
核心问题
你之前使用的Discord.py版本较旧,现在Discord.py版本更新后,Select、SelectOption、ActionRow这些组件已从discord根模块移至discord.ui子模块,同时旧版的on_select_option事件已被废弃。
具体修改步骤
修正导入路径
将代码中的导入语句:from discord import Select, SelectOption, ActionRow替换为:
from discord.ui import Select, SelectOption, ActionRow重构交互事件处理
旧版的on_select_option事件不再生效,改用组件绑定回调的方式处理选择交互。修改играть命令如下,同时删除原有的on_select_option事件函数:@bot.command() async def играть(ctx): # 定义选择菜单的回调函数 async def select_callback(interaction: discord.Interaction): selected_value = interaction.data["values"][0] await interaction.response.send_message(f"Вы выбрали: {selected_value}", ephemeral=True) options = [ SelectOption(label="Угадай число", value="option1"), SelectOption(label="Option 2", value="option2"), SelectOption(label="Option 3", value="option3"), ] select = Select(custom_id="select_menu", placeholder="Выберите опцию", options=options) select.callback = select_callback # 为选择菜单绑定回调 action_row = ActionRow(select) await ctx.send("Пожалуйста, выберите опцию:", components=[action_row])修复代码遗漏问题
原代码中info命令调用了registration_date但start命令未初始化该字段,需要在start命令的用户字典中添加:users[user_id] = { 'games': 0, 'currency': 0, 'registration_date': ctx.message.created_at.strftime("%Y-%m-%d %H:%M:%S") }更新Discord.py到最新版本(可选但推荐)
打开命令提示符执行以下命令,确保依赖版本兼容:pip install -U discord.py
修改后的完整可运行代码
import discord from discord.ext import commands from discord.ui import Select, SelectOption, ActionRow intents = discord.Intents.default() intents.members = True intents.message_content = True bot = commands.Bot(command_prefix='!', intents=intents) intents.typing = False intents.presences = False users = {} @bot.event async def on_ready(): print(f'Вошел в систему как {bot.user}') @bot.command() async def start(ctx): user_id = ctx.author.id if user_id not in users: users[user_id] = { 'games': 0, 'currency': 0, 'registration_date': ctx.message.created_at.strftime("%Y-%m-%d %H:%M:%S") } embed = discord.Embed( title="Успешная регистрация", description="Вы успешно зарегистрировались!", color=discord.Color.green() ) await ctx.send(embed=embed) else: embed = discord.Embed( title="Регистрация не удалась", description="Вы уже зарегистрированы!", color=discord.Color.red() ) await ctx.send(embed=embed) @bot.command() async def играть(ctx): async def select_callback(interaction: discord.Interaction): selected_value = interaction.data["values"][0] await interaction.response.send_message(f"Вы выбрали: {selected_value}", ephemeral=True) options = [ SelectOption(label="Угадай число", value="option1"), SelectOption(label="Option 2", value="option2"), SelectOption(label="Option 3", value="option3"), ] select = Select(custom_id="select_menu", placeholder="Выберите опцию", options=options) select.callback = select_callback action_row = ActionRow(select) await ctx.send("Пожалуйста, выберите опцию:", components=[action_row]) @bot.command() @commands.has_role('Chapter [10]') async def money(ctx, action, user: discord.Member, amount: int): user_id = user.id if user_id in users: if action == 'выдать': users[user_id]['currency'] += amount await ctx.send(f'Вы выдали {amount} валюты пользователю {user.name}') elif action == 'забрать': if users[user_id]['currency'] >= amount: users[user_id]['currency'] -= amount await ctx.send(f'Вы забрали {amount} валюты у пользователя {user.name}') else: await ctx.send('У пользователя недостаточно валюты!') else: await ctx.send('Недопустимое действие!') else: await ctx.send('Пользователь не зарегистрирован!') @bot.command() async def info(ctx): user_id = ctx.author.id if user_id in users: games = users[user_id]['games'] currency = users[user_id]['currency'] registration_date = users[user_id]['registration_date'] embed = discord.Embed(title='Статистика', color=discord.Color.blue()) embed.add_field(name='Количество игр', value=games, inline=False) embed.add_field(name='Количество валюты', value=currency, inline=False) embed.add_field(name='Дата регистрации', value=registration_date, inline=False) await ctx.send(embed=embed) else: await ctx.send('Вы не зарегистрированы!') bot.run('TOKEN')
内容的提问来源于stack exchange,提问作者xRoyse
相关产品推荐
相关产品推荐

