Python。代码重复多次,因为执行它的命令不同
Python. Code repeats several times because the command to execute it is different
我已经使用 Python 修补了一个 Discord 机器人,它已经可以正常工作了,但是有一个问题。
此代码会重复多次,每个帖子类别一次,现在我有随机的、有趣的、体育的、游戏的和新闻的,所以你可以看到它的冗余以及它会进一步变成什么,如果需要做更多的分类。
if '!random' in messageContent:
channel = int(chanRandom.strip('"'))
channel = client.get_channel(channel)
while c < 50:
if messageContent == '!random':
submission = next(x for x in randomList[sortListHot] if not x.stickied)
sortType = 'Hot sorting'
elif messageContent == '!random top':
submission = next(x for x in randomList[sortListTop] if not x.stickied)
sortType = 'Top sorting'
elif messageContent == '!random new':
submission = next(x for x in randomList[sortListNew] if not x.stickied)
sortType = 'New sorting'
with open(urlFile, 'r') as urlRead:
if str(submission.url) not in urlRead.read():
await channel.send(f"{submission.url}\n{submission.title}\n<https://reddit.com{submission.permalink}>")
await channel.send("-------------------------")
with open(urlFile, 'a+') as urlWrite:
urlWrite.write(str(f'{submission.url}\n'))
c += 2
else:
print(f'{messageContent} repost: {submission.url}')
await channel.send(sortType)
我现在的想法是创建一个包含每个可能命令的列表,但问题是使用变量 channel = int(chanRandom.strip('"'))
在正确的频道中发布,该变量根据使用的命令 channel = int(chanNews.strip('"'))
和等等。
还有一个内存使用问题,因为我认为机器人正在保存所有内容,但没有必要,但这是另一个问题。
感谢任何帮助。
我在这里看不到所有变量的内容,但是如果你想减少代码重复,我建议制作一个字典并将不同的变量映射到用户输入。
这是它的想法:
my_mapping = {
"!random": (sortListHot, "Hot sorting"),
"!random top": (sortListTop, "Top sorting"),
"!random new": (sortListNew, "New sorting")
}
sorting_type = my_mapping[messageContent.lower()][0] # sortListHot/Top/New
sorting_text = my_mapping[messageContent.lower()][1] # "Hot/Top/New sorting"
submission = next(x for x in randomList[sortingType] if not x.stickied)
将这些映射到字典还可以轻松灵活地添加更多条目(只需添加一个新键,其值是遵循当前模式的元组)。
为不区分大小写添加了 .lower()
。
我还可以建议查看命令装饰器而不是使用 on_message
事件。
参考文献:
- Dictionaries in Python
str.lower()
commands.Command()
- 强烈建议切换到此。
感谢@Diggy.,我能够完成代码。这是新版本:
messageContentTop = str.replace(messageContent, ' top','')
messageContentNew = str.replace(messageContent, ' new', '')
if messageContent or messageContentTop or messageContentNew in multiCom:
if 'top' in messageContent:
channel = int(multiCom[messageContentTop][3])
elif 'new' in messageContent:
channel = int(multiCom[messageContentNew][3])
else:
channel = int(multiCom[messageContent][3])
channel = client.get_channel(channel)
while c < 50:
if 'new' and 'top' not in messageContent:
submission = next(x for x in multiCom[messageContent][4] if not x.stickied)
sortType = 'Hot sorting'
elif 'top' in messageContent:
submission = next(x for x in multiCom[messageContentTop][5] if not x.stickied)
sortType = 'Top sorting'
elif 'new' in messageContent:
submission = next(x for x in multiCom[messageContentNew][6] if not x.stickied)
sortType = 'New sorting'
with open(urlFile, 'r') as urlRead:
if str(submission.url) not in urlRead.read():
await channel.send(f"{submission.url}\n{submission.title}\n<https://reddit.com{submission.permalink}>")
await channel.send("-------------------------")
with open(urlFile, 'a+') as urlWrite:
urlWrite.write(str(f'{submission.url}\n'))
c += 2
else:
print(f'{messageContent} repost: {submission.url}')
await channel.send(sortType)
multiCom
(多个命令,我会想到一个更好的名字)字典是这样设置的:
multiCom = {
'!random': ('!random', '!random top', 'random new', randomChan, reddit.subreddit(randomSubs).hot(), reddit.subreddit(randomSubs).top(), reddit.subreddit(randomSubs).new()),
'!funny': ('!funny', '!funny top', '!funny new', funnyChan, reddit.subreddit(funnySubs).hot(), reddit.subreddit(funnySubs).top(), reddit.subreddit(funnySubs).new()),
'!news': ('!news', '!news top', '!news new', newsChan, reddit.subreddit(newsSubs).hot(), reddit.subreddit(newsSubs).top(), reddit.subreddit(newsSubs).new())
}
randomChan
、funnyChan
、newsChan
是存储服务器频道ID的变量。
从旧版本中清理了大约 20kb,速度明显加快!
如果您有不适合简单模式的代码并希望使用类似于 switch/case 语句的结构,您可以编写一个辅助函数来模拟它:
def switch(value): yield lambda *match: value in match
用法示例:
for case in switch(messageContent):
if case('!random'):
submission = next(x for x in randomList[sortListHot] if not x.stickied)
sortType = 'Hot sorting'
elif case('!random top'):
submission = next(x for x in randomList[sortListTop] if not x.stickied)
sortType = 'Top sorting'
elif case('!random new'):
submission = next(x for x in randomList[sortListNew] if not x.stickied)
sortType = 'New sorting'
我已经使用 Python 修补了一个 Discord 机器人,它已经可以正常工作了,但是有一个问题。
此代码会重复多次,每个帖子类别一次,现在我有随机的、有趣的、体育的、游戏的和新闻的,所以你可以看到它的冗余以及它会进一步变成什么,如果需要做更多的分类。
if '!random' in messageContent:
channel = int(chanRandom.strip('"'))
channel = client.get_channel(channel)
while c < 50:
if messageContent == '!random':
submission = next(x for x in randomList[sortListHot] if not x.stickied)
sortType = 'Hot sorting'
elif messageContent == '!random top':
submission = next(x for x in randomList[sortListTop] if not x.stickied)
sortType = 'Top sorting'
elif messageContent == '!random new':
submission = next(x for x in randomList[sortListNew] if not x.stickied)
sortType = 'New sorting'
with open(urlFile, 'r') as urlRead:
if str(submission.url) not in urlRead.read():
await channel.send(f"{submission.url}\n{submission.title}\n<https://reddit.com{submission.permalink}>")
await channel.send("-------------------------")
with open(urlFile, 'a+') as urlWrite:
urlWrite.write(str(f'{submission.url}\n'))
c += 2
else:
print(f'{messageContent} repost: {submission.url}')
await channel.send(sortType)
我现在的想法是创建一个包含每个可能命令的列表,但问题是使用变量 channel = int(chanRandom.strip('"'))
在正确的频道中发布,该变量根据使用的命令 channel = int(chanNews.strip('"'))
和等等。
还有一个内存使用问题,因为我认为机器人正在保存所有内容,但没有必要,但这是另一个问题。
感谢任何帮助。
我在这里看不到所有变量的内容,但是如果你想减少代码重复,我建议制作一个字典并将不同的变量映射到用户输入。
这是它的想法:
my_mapping = {
"!random": (sortListHot, "Hot sorting"),
"!random top": (sortListTop, "Top sorting"),
"!random new": (sortListNew, "New sorting")
}
sorting_type = my_mapping[messageContent.lower()][0] # sortListHot/Top/New
sorting_text = my_mapping[messageContent.lower()][1] # "Hot/Top/New sorting"
submission = next(x for x in randomList[sortingType] if not x.stickied)
将这些映射到字典还可以轻松灵活地添加更多条目(只需添加一个新键,其值是遵循当前模式的元组)。
为不区分大小写添加了 .lower()
。
我还可以建议查看命令装饰器而不是使用 on_message
事件。
参考文献:
- Dictionaries in Python
str.lower()
commands.Command()
- 强烈建议切换到此。
感谢@Diggy.,我能够完成代码。这是新版本:
messageContentTop = str.replace(messageContent, ' top','')
messageContentNew = str.replace(messageContent, ' new', '')
if messageContent or messageContentTop or messageContentNew in multiCom:
if 'top' in messageContent:
channel = int(multiCom[messageContentTop][3])
elif 'new' in messageContent:
channel = int(multiCom[messageContentNew][3])
else:
channel = int(multiCom[messageContent][3])
channel = client.get_channel(channel)
while c < 50:
if 'new' and 'top' not in messageContent:
submission = next(x for x in multiCom[messageContent][4] if not x.stickied)
sortType = 'Hot sorting'
elif 'top' in messageContent:
submission = next(x for x in multiCom[messageContentTop][5] if not x.stickied)
sortType = 'Top sorting'
elif 'new' in messageContent:
submission = next(x for x in multiCom[messageContentNew][6] if not x.stickied)
sortType = 'New sorting'
with open(urlFile, 'r') as urlRead:
if str(submission.url) not in urlRead.read():
await channel.send(f"{submission.url}\n{submission.title}\n<https://reddit.com{submission.permalink}>")
await channel.send("-------------------------")
with open(urlFile, 'a+') as urlWrite:
urlWrite.write(str(f'{submission.url}\n'))
c += 2
else:
print(f'{messageContent} repost: {submission.url}')
await channel.send(sortType)
multiCom
(多个命令,我会想到一个更好的名字)字典是这样设置的:
multiCom = {
'!random': ('!random', '!random top', 'random new', randomChan, reddit.subreddit(randomSubs).hot(), reddit.subreddit(randomSubs).top(), reddit.subreddit(randomSubs).new()),
'!funny': ('!funny', '!funny top', '!funny new', funnyChan, reddit.subreddit(funnySubs).hot(), reddit.subreddit(funnySubs).top(), reddit.subreddit(funnySubs).new()),
'!news': ('!news', '!news top', '!news new', newsChan, reddit.subreddit(newsSubs).hot(), reddit.subreddit(newsSubs).top(), reddit.subreddit(newsSubs).new())
}
randomChan
、funnyChan
、newsChan
是存储服务器频道ID的变量。
从旧版本中清理了大约 20kb,速度明显加快!
如果您有不适合简单模式的代码并希望使用类似于 switch/case 语句的结构,您可以编写一个辅助函数来模拟它:
def switch(value): yield lambda *match: value in match
用法示例:
for case in switch(messageContent):
if case('!random'):
submission = next(x for x in randomList[sortListHot] if not x.stickied)
sortType = 'Hot sorting'
elif case('!random top'):
submission = next(x for x in randomList[sortListTop] if not x.stickied)
sortType = 'Top sorting'
elif case('!random new'):
submission = next(x for x in randomList[sortListNew] if not x.stickied)
sortType = 'New sorting'