首页 文章

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

提问于
浏览
2

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

例如,我已经为我正在构建的Discord BOT编写了一个名为YouTubeAPI的小类 . Discord.py库为其所有函数使用asyncio,但我的类没有 . 我的课程(YouTubeAPI)仅用于从YouTube Data API V3中检索用户发布的最新视频的数据 . 我实际上正在尝试构建一个BOT,让我及时了解所有人发布的视频 .

但是为了使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')

如果这个帖子含糊不清地解释,我非常抱歉,但我完全不知道如何使用asyncio或类似的东西,我发现自己在一个我几乎找不到这个新概念的文档的地方 .

3 回答

  • 0

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

    client.run("token")
    

    始终在Discord.PY机器人的最后一行,只要函数发生,机器人就会一直运行,直到发生client.close()函数或环境关闭 .

  • 0

    您可以使用 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')
    
  • 1

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

相关问题