2017-02-09 59 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()函數發生,或環境被關閉。