一个开始学习新的Python 3.5 Asyncio(协同程序)|Discord.py BOT崩溃的好地方



所以,我似乎没有找到任何关于在python中使用新的异步模块的好教程(async、await等)。此外,从我看过的所有教程中,这个概念描述得很差,我似乎无法理解协程的想法。我的意思是,这个概念背后的想法并没有那么难,但没有一个地方可以让我确切地了解协同程序能做什么,不能做什么,以及如何使用它们。

例如,我为目前正在构建的Discord BOT编写了一个名为YouTubeAPI的小类。Discord.py库的所有函数都使用asyncio,但我的类没有。我的类(YouTubeAPI)的唯一目的是从YouTube data API V3检索用户发布的最新视频的数据。事实上,我正试图建立一个BOT,让我了解有人发布的所有视频的最新情况。

但为了让BOT发挥作用,我需要制作一个update()函数,定期获取所有视频,这样我就可以获取最新的视频。问题是更新函数需要封装在while True循环(或类似的循环)中,这样我就可以保持列表的最新状态。如果我构建了一个无限循环,那么我会遇到BOT的问题(使BOT崩溃且无法使用)。

所以,我想也许我可以学习新的异步模块并用这种方式解决问题。遗憾的是,我一无所获。

下面是一些删除了所有API密钥的代码,这样你就可以更容易地看到我的问题:

from Api_Test import YoutubeAPI
import discord
import asyncio
YoutubeName = 'Vsauce'
GOOGLE_API = 'API KEY'
print('Collecting YouTube Data.')
api = YoutubeAPI(GOOGLE_API, YoutubeName) # create object that will get all info for the name 'Vsauce'
print('YouTube Data collected succesfully.')
print('Starting bot.')
def getLastVideo():
return api.videosData[0] # api.videosData looks like: [[title, link],[title, link],[title, link],]
client = discord.Client()
@client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
await client.send_message('Now testing: Last {} videos!'.format(YoutubeName))

#While Loop that keeps the api.videosData up-to-date and runs "await client.send_message('new video: title + ink')" if new video found in the list
client.run('Discord BOT token')

如果这篇文章听起来解释含糊,我非常抱歉,但我完全不知道如何使用asyncio或类似的东西,我发现自己在一个几乎没有关于这个新概念的文档的地方。

您可以使用ensure_future()来运行while循环。在这里,当调用on_ready时循环开始,并运行直到机器人关闭

@client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
await client.send_message('Now testing: Last {} videos!'.format(YoutubeName))
asyncio.ensure_future(update_data(), client.loop) # Starts the infinite loop when the bot starts
async def update_data():
while True:
# Do the things you need to do in this loop
await asyncio.sleep(1) # sleep for 1 second
client.run('Discord BOT token')

您可以在后台中通过asyncio.ensure_future运行一个函数(类似于从Youtube检索数据的函数)

我自己的机器人的一个例子:

games = [
'try :help',
'with Atom.io',
'with Python',
'HuniePop'
]
async def randomGame():
while True:
await bot.change_presence(game=discord.Game(name=random.choice(games)))
await asyncio.sleep(10*60) # 10 Minutes

@client.event
async def on_ready():
print('Logged in as')
print('Bot-Name: {}'.format(bot.user.name))
print('Bot-ID: {}'.format(bot.user.id))
...
bot.gamesLoop = asyncio.ensure_future(randomGame())

有关这方面的更多信息,请点击此处:https://docs.python.org/3/library/asyncio-task.html

但是你实际在哪里运行client.run()函数?因为你不能在循环中运行它。这样你就能让机器人崩溃。还是我错了?

client.run("token")

总是在Discord.PY机器人的最后一行,一旦函数发生,机器人就会一直运行,直到客户端.close()函数发生,或者环境关闭。

最新更新