提问人:smithmarci 提问时间:10/8/2023 最后编辑:smithmarci 更新时间:10/21/2023 访问量:54
用 Python 编写的简单 Discord 聊天机器人,用作具有多个数据源的字典
Simple Discord chatbot written in Python that serves as a dictionary with multiple data sources
问:
我想用一个聊天机器人来帮助我在 Discord 上的翻译社区,该聊天机器人可以用作字典、词汇数据库,但词库的大小将是巨大的,我想将数据源拆分为几个单独的文件,就像他们在印刷词典中处理首字母的字母索引一样。我有一个基本程序代码,它已经适用于一个文件,但我不知道如何实现多文件查找和评估方法。对不起,我的英语不好(显然,这不是我的母语)!另外,请耐心等待,因为我是编程菜鸟! 你能帮我解决这个问题吗?
这些是我的文件。它旨在仅回复私人消息并在 DM 中进行交流。
我的数据源 #1 pool0_help.py
def get_response(message: str) -> str:
p_message = message.lower()
#HELP MESSAGE
#------------
if p_message == '?help':
return 'Type in any name or phrase that comes to your mind, and I will tell you what its equivalent is in your language.\r\n \r\nTo see all phrases under index B, type: poolB'
#FALLBACK
#--------
return 'I am not sure I understood it correctly!'
我的潜在数据源 #3 pool2_B.py
def get_response(message: str) -> str:
p_message = message.lower()
#INDEX B
#-------
poolB = [
"**baldur\'s gate**" ,
"**baldur\'s mouth gazette**" ,
"**beastlands**" ,
"**blighted village**" ,
"**blushing mermaid**"
]
if p_message == "b-index":
return '? *B* ::\r\n> ' + str(poolB)
if p_message == 'baldur\'s gate':
return '? *' + p_message + '*\r\n= **Baldurkapuja**'
if p_message == 'baldur\'s mouth gazette':
return '? *' + p_message + '*\r\n= **Baldur Szája Hírmondó**'
if p_message == 'beastlands':
return '? *' + p_message + '*\r\n= **Fenevadföld**'
if p_message == 'blighted village':
return '? *' + p_message + '*\r\n= **Felégetett falu**'
if p_message == 'blushing mermaid':
return '? *' + p_message + '*\r\n= **Piruló sellő**'
#FALLBACK
#--------
return 'There is no such word, name or pharse in my database, sorry!'
bot.py
import discord
import pool0_help
import pool1_A
import pool2_B
import pool3_C
async def send_message(message, user_message, is_private):
try:
response = pool0_help.get_response(user_message)
await message.author.send(response) if is_private else await message.author.send(response)
except Exception as e:
print(e)
def run_discord_bot():
TOKEN = 'my Discord token'
intents = discord.Intents.default()
intents.members = True
#intents.message_content = True
client = discord.Client(intents=intents)
@client.event
async def on_ready():
print(f'{client.user} is now running!')
@client.event
async def on_message(message):
if message.author == client.user:
return
username = str(message.author)
user_message = str(message.content)
channel = str(message.channel)
print(f'{username} said: "{user_message}" in ({channel})')
if user_message[0] == '!':
user_message = user_message[1:]
await send_message(message, user_message, is_private=True)
else:
await send_message(message, user_message, is_private=True)
client.run(TOKEN)
main.py
import bot
if __name__ == '__main__':
bot.run_discord_bot()
正如我之前提到的,它按预期与一个数据源(在本例中为“pool0_help.py”)一起工作。但无论我如何尝试,我都无法让它处理更多文件。
存储起来很不方便,编辑一个包含数百个单词的文件也很麻烦,这就是为什么我想将其拆分为更小的词池。
请您告诉我要修改什么以及如何使这本词典工作吗?这对我们来说将是一个巨大的帮助!任何帮助将不胜感激!先谢谢你!
答:
您需要以某种方式确定需要为每条传入消息使用哪个消息。在这里,您有两种选择:要么尝试每个池,直到其中一个池正常工作,要么创建一些事先确定池的逻辑。pool
方法一:尝试每个池,直到它起作用
要尝试每个池,您可以将池放入一个,然后调用直到您得到一些东西。如果选择此选项,则如果响应不匹配,池中的函数应返回(即 no return 语句)。例如:list
get_response
get_response
None
# pool0_help.py
def get_response(message: str) -> str:
p_message = message.lower()
if p_message == '?help':
return 'Type in any name or phrase that comes to your mind, and I will tell you what its equivalent is in your language.\r\n \r\nTo see all phrases under index B, type: poolB'
# pool2_B.py
def get_response(message: str) -> str:
p_message = message.lower()
poolB = [
"**baldur\'s gate**" ,
"**baldur\'s mouth gazette**" ,
"**beastlands**" ,
"**blighted village**" ,
"**blushing mermaid**"
]
if p_message == "b-index":
return '? *B* ::\r\n> ' + str(poolB)
# a bunch more `if`s...
# bot.py
import pool0_help
import pool1_A
import pool2_B
import pool3_C
POOLS = [pool0_help, pool1_A, pool2_B, pool3_C, ...]
async def send_message(message, user_message, is_private):
try:
for pool in POOLS:
response = pool.get_response(user_message)
if not response:
continue
await message.author.send(response) if is_private else await message.author.send(response)
return
await message.author.send('Unknown message') if is_private else await message.author.send('Unknown message')
except Exception as e:
print(e)
# ... rest of your code ...
方法二:使用首字母对应的池
要事先检查要使用的池,可以创建一个 从第一个字母到模块对象。您的可能看起来像:dict
pool
bot.py
# bot.py
import pool0_help
import pool1_A
import pool2_B
import pool3_C
POOLS = {'?': pool0_help, 'a': pool1_A, 'b': pool2_B, 'c': pool3_C, ...}
async def send_message(message, user_message, is_private):
try:
ch = user_message[0]
if ch not in POOLS:
await message.author.send('Unknown message') if is_private else await message.author.send('Unknown message')
response = POOLS[ch].get_response(user_message)
await message.author.send(response) if is_private else await message.author.send(response)
except Exception as e:
print(e)
# ... rest of your code ...
评论
Traceback (most recent call last):