开始学习新 Python 3.5 Asyncio(协程)的好地方 | Discord.py 机器人崩溃

A good place to start learning the new Python 3.5 Asyncio (coroutines) | Discord.py BOT crash

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

例如,我为目前正在构建的 Discord BOT 编写了一个名为 YouTubeAPI 的小 class。 Discord.py 库的所有功能都使用 asyncio,但我的 class 没有。我的 class (YouTubeAPI) 的唯一目的是从 YouTube 数据 API V3 中检索有关用户 post 编辑的最新视频的数据。实际上,我正在尝试构建一个 BOT,让我了解某人正在 posting 的所有视频的最新信息。

但是为了让 BOT 正常工作,我需要制作一个 update() 函数来定期获取所有视频,以便我可以获得最新的视频。问题是更新函数需要包含在 while True 循环(或类似的东西)中,这样我才能使列表保持最新。如果我构建一个无限循环,那么我将 运行 陷入 BOT 的问题(导致 BOT 崩溃和无法使用)。

所以,我想也许我可以学习新的 asyncio 模块并以这种方式解决问题。可悲的是我什么也没找到。

下面是一些删除了所有 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')

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

您可以在后台通过 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

But where do you actually run the client.run () function? Because you can't run it in the loop. That way you wojld make the bot crash. Or am I wrong?

client.run("token")

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

您可以使用 ensure_future() 到 运行 您的 while 循环。 这里的循环在调用 on_ready 和 运行s 时开始,直到 bot 关闭

@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')