9

私は使用asyncioして美しいaiohttp。主なアイデアは、サーバーにリクエストを送信し(リンクを返す)、すべてのリンクからファイルを並行してダウンロードすることです(のようなもの)。

コード:

import aiohttp
import asyncio

@asyncio.coroutine
def downloader(file):
    print('Download', file['title'])
    yield from asyncio.sleep(1.0) # some actions to download
    print('OK', file['title'])


def run():
    r = yield from aiohttp.request('get', 'my_url.com', True))
    raw = yield from r.json()
    tasks = []
    for file in raw['files']:
        tasks.append(asyncio.async(downloader(file)))
        asyncio.wait(tasks)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())

しかし、実行しようとすると、多くの「ダウンロード...」出力があり、

Task was destroyed but it is pending!

そして、「OK + ファイル名」については何もありません。

どうすれば修正できますか?

4

1 に答える 1

12

yield fromへの呼び出しを忘れましたasyncio.wait。また、おそらくインデントも間違っています。リスト全体を繰り返し処理した後にのみ実行する必要がありますraw['files']。両方の間違いを修正した完全な例を次に示します。

import aiohttp
import asyncio

@asyncio.coroutine
def downloader(file):
    print('Download', file['title'])
    yield from asyncio.sleep(1.0) # some actions to download
    print('OK', file['title'])

@asyncio.coroutine
def run():
    r = yield from aiohttp.request('get', 'my_url.com', True))
    raw = yield from r.json()
    tasks = []
    for file in raw['files']:
        tasks.append(asyncio.async(downloader(file)))
    yield from asyncio.wait(tasks)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())

を呼び出さないと、ファイルのリスト全体を反復処理した直後yield fromrun終了します。つまり、スクリプトが終了し、未完了のdownloaderタスク全体が破棄され、警告が表示されます。

于 2015-03-27T18:33:31.763 に答える