Asyncio event_loop declared outside the class with asyncio.coroutine methods does not execute with the AttributeError: "NoneType" attribute does not have a "select" attribute

Learning the asyncio module of Python 3.4.0, I am trying to create a class with asyncio.coroutine methods that are called from event_loop outside the class.

My working code is below.

import asyncio

class Foo():
    @asyncio.coroutine
    def async_sleep(self):
        print('about to async sleep')
        yield from asyncio.sleep(1)

    @asyncio.coroutine
    def call_as(self):
        print('about to call ass')
        yield from self.async_sleep()

    def run_loop(self):
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.call_as())
        print('done with loop')
        loop.close()

a = Foo()
a.run_loop()

loop = asyncio.get_event_loop()
loop.run_until_complete(a.call_as())

The call a.run_loop()provides output as expected:

python3 async_class.py
about to call ass
about to async sleep
done with loop

However, as soon as event_loop tries to process a.call_as(), I get the following Traceback:

Traceback (most recent call last):
  File "async_class.py", line 26, in <module>
    doop.run_until_complete(asyncio.async(a.call_ass()))
  File "/opt/boxen/homebrew/opt/pyenv/versions/3.4.0/lib/python3.4/asyncio/base_events.py", line 203, in run_until_complete
self.run_forever()
  File "/opt/boxen/homebrew/opt/pyenv/versions/3.4.0/lib/python3.4/asyncio/base_events.py", line 184, in run_forever
self._run_once()
  File "/opt/boxen/homebrew/opt/pyenv/versions/3.4.0/lib/python3.4/asyncio/base_events.py", line 778, in _run_once
event_list = self._selector.select(timeout)
AttributeError: 'NoneType' object has no attribute 'select'

I tried to wrap up a.call_as()in asyncio.Task(), asyncio.async()and the failure of the same.

+4
source share
2 answers

As it turns out, the problem was in the context of the event loop.

asyncio . .get_event_loop().

a.run_loop Foo.run_loop.

, , .

, loop = asyncio.get_event_loop() a.run_loop __main__. , Foo.run_loop, __main__ None.

, __main__, ..

new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)

__main__, new_loop.run_until_complete(a.call_as())

+5

, eventloop Foo.run_loop()

BaseEventLoop.close

. . .

, .

. .

+1

Source: https://habr.com/ru/post/1538106/


All Articles