web-dev-qa-db-ja.com

"RuntimeError:このイベントループはすでに実行されています"; aiohttp、asyncio、およびIDE "spyder3" in python 3.6.5

「RuntimeError:このイベントループはすでに実行されています」というランタイムエラーが発生する理由を理解するのに苦労しています。 " https://aiohttp.readthedocs.io/en/stable/ "からコードスニペットを実行しようとしましたが、同じ問題が発生し続けます。

チュートリアルのコードスニペット:


import aiohttp
import asyncio
import async_timeout

async def fetch(session, url):
    async with async_timeout.timeout(10):
        async with session.get(url) as response:
            return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://python.org')
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

チュートリアルスニペットからの結果(スパイダーIDEからコードを実行している間):


RuntimeError:このイベントループはすでに実行されています

<!doctype html>"

...(その他のhtml)


個人コードスニペット(上記のチュートリアルからではありません):


import aiohttp
import asyncio
import time

urls = ['https://api.robinhood.com/quotes/c4f6720a-0364-4e7b-8c41-705696759e1a/']

async def fetch(client, url):
    async with client.request('get', url) as response:
        if response.status == 200:
            data = await response.text()
        else:
            data = []
        print(data)
        return(data)

async def get_async_urls(urls):
    async with aiohttp.ClientSession() as client:
        return await asyncio.gather(*(fetch(client, url) for url in urls))

if __name__ == '__main__':
    t0 = time.time()
    loop = asyncio.get_event_loop()
    results = loop.run_until_complete(get_async_urls(urls))
    print(results)
    t1 = time.time()
    total_time = t1-t0
    loop.close()

パーソナルスニペットからの結果(スパイダーIDEからコードを実行している間):


RuntimeError:このイベントループはすでに実行されています

{"ask_price": "14.9000"、 "ask_size":100、 "bid_price": "14.0100"、 "bid_size":100、 "last_trade_price": "14.7900"、 "last_extended_hours_trade_price": "14.7900"、 "previous_close": " 14.3600、 "adjusted_previous_close": "14.3600"、 "previous_close_date": "2018-05-07"、 "symbol": "SURF"、 "trading_halted":false、 "has_traded":true、 "last_trade_price_source": "consolidated" 、 "updated_at": "2018-05-08T20:01:21Z"、 "instrument": " https://api.robinhood.com/instruments/43d56335-f2f6-4711-b650-55be2396f814/ = "}


パーソナルスニペットからの結果(cmd "python personal_snippet.py"から実行中):


{"ask_price": "14.9000"、 "ask_size":100、 "bid_price": "14.0100"、 "bid_size":100、 "last_trade_price": "14.7900"、 "last_extended_hours_trade_price": "14.7900"、 "previous_close": " 14.3600、 "adjusted_previous_close": "14.3600"、 "previous_close_date": "2018-05-07"、 "symbol": "SURF"、 "trading_halted":false、 "has_traded":true、 "last_trade_price_source": "consolidated" 、 "updated_at": "2018-05-08T20:01:21Z"、 "instrument": " https://api.robinhood.com/instruments/43d56335-f2f6-4711-b650-55be2396f814/ = "} ['{" ask_price ":" 14.9000 "、" ask_size ":100、" bid_price ":" 14.0100 "、" bid_size ":100、" last_trade_price ":" 14.7900 "、" last_extended_hours_trade_price ":" 14.7900 "、 "previous_close": "14.3600"、 "adjusted_previous_close": "14.3600"、 "previous_close_date": "2018-05-07"、 "symbol": "SURF"、 "trading_halted":false、 "has_traded":true、 "last_trade_price_source ":"統合 "、" updated_at ":" 2018-05-08T20:01:21Z "、"機器 ":" https://api.robinhood.com/instruments/43d56335-f2f6-4711-b650 -55be2396f814 / "} ']


上記の結果は、Spyder IDEに関連する問題を示しているようです。


2つの質問があります:

  1. なぜこのエラーが発生するのですか?チュートリアルコードを実行しても、他の人にはこのエラーが発生しないようです。 (回答の可能性:SPYDER3のバグの可能性)

    これはスパイダーIDEでのみ発生するようです。 cmdプロンプトから両方のコードスニペットを実行しましたが、エラーは表示されませんでした。提案してくれた@MikhailGerasimovに感謝します。

  2. (コードの2番目のスニペットに)2つの印刷コマンドがあり、「データ」のセットが1つだけ印刷された場合、データが元の呼び出しに戻らないのはなぜですか(結果= loop.run_until_complete(get_async_urls(urls)))(回答の可能性:SPYDER3のバグの可能性)

    これはスパイダーIDEでのみ発生するようです。 cmdプロンプトから2番目のコードスニペットを実行すると、両方の印刷が表示されました。提案してくれた@MikhailGerasimovに感謝します。




両方の質問に(おそらく)回答があります。 spyder IDEに問題を送信するときに、この質問を参照します。物事のスパイダー側で物事が進化するにつれて、私はこれを更新し続けます。彼らが戻ってきて、問題が彼らにあるのではないと言った場合、私は少し異なる形式で質問を再開します。

助けてくれてありがとう!




Spyder IDEのgithubで参照されている問題の送信へのリンク: https://github.com/spyder-ide/spyder/issues/7096




7

この問題はIDE使用済み(Spyder3)に関連しているようです。昨夜PyCharmコミュニティエディションでコードを実行しようとしました。コードは問題なく実行されました。

Spyder3にバグを提出しました。

2

運が良かったのかもしれませんが、トルネードをダウングレードしました。 "tornado 5.0の更新後にasyncioevent_loopを呼び出せない" を参照してください。

1
Dylan_Larkin

私はSpyderで同じ問題を抱えています、私のために働いた唯一の解決策は nest_asyncio を使用することでした

コマンドを使用してnest_asyncioをインストールします

pip install nest_asyncio

以下の行をファイルに追加します

import nest_asyncio
nest_asyncio.apply()

そして、問題を修正する必要があります。


ドキュメントから

設計上、asyncioはそのイベントループをネストすることを許可していません。これには実際的な問題があります。イベントループがすでに実行されている環境では、タスクを実行して結果を待つことは不可能です。そうしようとすると、「RuntimeError:このイベントループはすでに実行されています」というエラーが発生します。

この問題は、Webサーバー、GUIアプリケーション、Jupyterノートブックなどのさまざまな環境で発生します。

このモジュールはasyncioにパッチを適用して、asyncio.runとloop.run_until_completeをネストして使用できるようにします。

1
Rajshekar Reddy

Spyderは独自のイベントループを実行しているように見えます。 1つのスレッドで2つのイベントループを実行することはできません。

asyncio.run(coro、*、debug = False)

同じスレッドで別のasyncioイベントループが実行されている場合、この関数を呼び出すことはできません。

これは私のために働いたものです。他に実行中のループがない場合は、独自のループを開始します。

import asyncio

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    await say_after(2, 'done')

await say_after(1, 'ahoy')    

loop = asyncio.get_event_loop()
print(loop) # <_WindowsSelectorEventLoop running=True closed=False debug=False>
if loop.is_running() == False:
    asyncio.run(main())
else:
    await main()
0
Rav