[解決済み] asyncio.ensure_future vs. BaseEventLoop.create_task vs. simple coroutine?
質問
私はasyncioのいくつかの基本的なPython 3.5のチュートリアルを見てきましたが、様々なフレーバーで同じ操作を行っています。 このコードでは
import asyncio
async def doit(i):
print("Start %d" % i)
await asyncio.sleep(3)
print("End %d" % i)
return i
if __name__ == '__main__':
loop = asyncio.get_event_loop()
#futures = [asyncio.ensure_future(doit(i), loop=loop) for i in range(10)]
#futures = [loop.create_task(doit(i)) for i in range(10)]
futures = [doit(i) for i in range(10)]
result = loop.run_until_complete(asyncio.gather(*futures))
print(result)
を定義している上記の三つのバリアントはすべて
futures
唯一の違いは、3 番目のバリエーションでは実行が順番通りでないことです (ほとんどの場合、これは問題ではないはずです)。他に何か違いがあるのでしょうか?最も単純なバリアント(コルーチンのプレーンなリスト)を使用できないケースはあるのでしょうか?
どのように解決するのですか?
実際の情報です。
Python 3.7からスタート
asyncio.create_task(coro)
高レベル関数
が追加されました。
が追加されました。
コアタイムからタスクを生成する他の方法の代わりに、この方法を使う必要があります。ただし、任意の待ち行列からタスクを生成する必要がある場合には
asyncio.ensure_future(obj)
.
古い情報です。
ensure_future
対
create_task
ensure_future
は
Task
から
coroutine
. 引数に応じた様々な方法でタスクを作成します(例えば
create_task
を使うなど)。
create_task
は抽象的なメソッドで
AbstractEventLoop
. イベントループによって、この関数を異なる方法で実装することができます。
を使用する必要があります。
ensure_future
を使ってタスクを作成します。その際
create_task
は、独自のイベントループ型を実装する場合のみ必要です。
更新しました。
@bj0 が指摘した グイドの答え を参照してください。
<ブロッククオート
のポイントは
ensure_future()
のポイントは、もしあなたが
コルーチンか
Future
のどちらかです (後者には
Task
を含むからです。
のサブクラスであるためです。
Future
のサブクラスだからです)。
でしか定義されていないメソッドを
Future
にのみ定義されているメソッドを呼び出したい場合 (おそらく唯一の有用な
例としては
cancel()
). それがすでに
Future
(または
Task
) これは
は何もしませんが、コルーチンである場合は
を包む
で囲みます。
Task
.
コルーチンがあることが分かっていて、それをスケジュールしたい場合。
を使うのが正しいAPIです。
create_task()
. を使うべき唯一の場合です。
を呼び出す必要があります。
ensure_future()
を呼び出す必要があるのは、(asyncio 自身の API のような) API を提供するときだけです。
asyncio自身のAPIのように)コルーチンまたは
Future
と
を必要とするような API を提供する場合です。
Future
.
といった具合です。
<ブロッククオート
結局のところ、私は今でも
ensure_future()
は適切な
は、めったに必要とされない機能の断片に対して、適切な不明瞭な名前であると思います。コルーチンから
を使用する必要があります。
loop.create_task()
. 多分、そのためのエイリアスがあるはずです
asyncio.create_task()
?
自分でも意外です。私の主な動機は
ensure_future
を使う一番の動機は、ループのメンバーである
create_task
(考察
には
を追加するようなアイデアもあります。
asyncio.spawn
または
asyncio.create_task
).
また、私の意見としては、あらゆる種類の
Awaitable
を処理できるユニバーサル関数を使うのが便利だと思います。
しかし、Guidoの答えは明確です。
"コルーチンからタスクを作成するときは、適切な名前を持つ
loop.create_task()
を使うべきです。
コルーチンはいつタスクにラップされるべきか?
コルーチンをタスクでラップする - コルーチンをバックグラウンドで開始する方法です。以下はその例です。
import asyncio
async def msg(text):
await asyncio.sleep(0.1)
print(text)
async def long_operation():
print('long_operation started')
await asyncio.sleep(3)
print('long_operation finished')
async def main():
await msg('first')
# Now you want to start long_operation, but you don't want to wait it finised:
# long_operation should be started, but second msg should be printed immediately.
# Create task to do so:
task = asyncio.ensure_future(long_operation())
await msg('second')
# Now, when you want, you can await task finised:
await task
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
出力します。
first
long_operation started
second
long_operation finished
を置き換えることができます。
asyncio.ensure_future(long_operation())
を単に
await long_operation()
で違いを実感してください。
関連
-
[解決済み] リストの要素を値で削除する簡単な方法はありますか?
-
[解決済み] models.pyを複数のファイルに分割する
-
[解決済み] Pythonでnumpy.linalg.eigを使用した後の固有値と関連する固有ベクトルのソート
-
[解決済み] pathlib.Pathオブジェクトの絶対パスを取得するには?
-
[解決済み] 条件を満たした場合にNumpyの要素を置き換える
-
[解決済み] python: 2階層上のディレクトリを取得する
-
[解決済み] ネストした辞書の項目からpandasのDataFrameを構築する
-
[解決済み] イテラブルを一定サイズのチャンクに分割する方法
-
[解決済み] Pythonでファイルがバイナリ(非テキスト)かどうかを検出するにはどうしたらいいですか?
-
[解決済み] 関数が受け取るキーワード引数をリストアップできますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] googletransがエラー 'NoneType' オブジェクトに 'group' 属性がない、と言って動かなくなった。
-
[解決済み] テンプレートファイル変更時にFlaskアプリを再読み込みする
-
[解決済み] Pythonでzip(*[iter(s)]*n)はどのように動作するのですか?
-
[解決済み] Pythonで関数の引数として辞書の項目を渡すには?重複
-
[解決済み] pathlib.Pathオブジェクトの絶対パスを取得するには?
-
[解決済み] python BeautifulSoup テーブルのパース
-
[解決済み] 標準のjsonモジュールでfloatをフォーマットする
-
[解決済み] 2つの日付の間の月数を求める最良の方法
-
[解決済み] readonlyプロパティをmockでモックするには?
-
[解決済み] Python のモック patch.object を使って、他のメソッド内で呼び出されたメソッドの戻り値を変更する。