2017-02-09 80 views
2

所以,我似乎没有找到任何关于在Python中使用新的asyncio模块的好教程(异步,等待等)。另外,从我看过的所有教程中,这个概念描述得很差,我似乎无法围绕协程的想法包围我的头脑。我的意思是,这个概念背后的想法并不难,但没有一个地方我可以准确了解协同程序可以做什么以及不可以做什么,以及如何使用它们。开始学习新的Python 3.5 Asyncio(协程)的好地方| Discord.py BOT崩溃

例如,我写了一个叫做YouTubeAPI的小类,用于我目前正在构建的不和BOT。 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或类似的东西,我发现自己在一个地方,我几乎找不到有关这个新概念的文档。

+0

这可能帮助:ASYNCIO用户文档(http://asyncio.readthedocs.io/en/latest/)。 – Vincent

+0

尝试https:// stackoverflow。com/questions/41785617/python-asyncio-task-ordering,http://lucumr.pocoo.org/2016/10/30/i-dont-understand-asyncio/和https://community.nitrous.io /教程/异步编程与 - 蟒-3。 – boardrider

回答

1

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

您可以运行的功能(如一些检索来自YouTube的数据)通过asyncio.ensure_future背景

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

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

+0

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

0

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

client.run("token") 

总是在Discord.PY机器人的最后一行,只要功能可取代机器人不断运行,直到一个client.close()函数发生,或环境被关闭。