- Every task should be awaited somewhere so you’ve got an exception
- Don’t use features directly
- Use Executors for the long term tasks(for example - some calculations)
- don’t use __del__ method for the resources cleanup. Use async metethod, for example await obj.close() or context manager async with obj:
- to replace event loop it’s better to change default loop fabric at the asyncio
It should be used in case task should be finished in any case, even with closed connection
async def handler(request): await asyncio.shield(request.config['db'].execute("UPDATE ...")) return web.Response(text="OK")
Or you may use aiojobs library
Should be used for some small tasks as logging, tracing, etc.
Example of yield as generator:
def generator(x): # here generator will be interupted and wait for next call yield x yield x*2 # example: gen = generator(10) next(gen) # out: 10 next(gen) # out: 20
Example of yield as coroutine:
def writer(): while True: # rcv a data w = yield print("was received:", w) w = writer() # initialize the generator w.send(None) w.send(10) # out: "was received: 10" w.send("some text") # out: "was received: some text"
Example usage of yield from syntax:
# define our generator def generator(): for i in range(4): yield i # manually fetch data def fetcher(g): for fetch in g: yield fetch # yield from fetcher def fetcher_yield(g): yield from g # examples: fetch_results = fetcher(generator()) for i in fetch_results: print(i) fetch_results = fetcher_yield(generator()) for i in fetch_results: print(i)
It is possible to create object at generator and after only change it’s value. This will reduce memory consumption, but can lead to some errors: