To execute several asynchronous methods in order one by one (the following method does not start until the previous one is completed):
o = await o.m1() o = await o.m2() o = await o.m3()
As shown by @Sergey Gornostaev , it is easy to define such a Chain class so that you can write:
await Chain(o).m1().m2().m3()
In real code, method names are usually longer and therefore both approaches must be equally readable. The first approach is more explicit (and therefore it may be clearer what is happening).
Such a fluent interface should be used extremely moderately in Python (the code on Python usually follows the incompatible Command – query separation principle ) and see if there is a better, more idiomatic alternative in each particular case. In cases where such an API is justified, it is desirable to return immutable objects from similar methods, for example, as the Query API in SQLAlchemy does.
If you already have a list of coroutines, then you can use a regular for cycle to execute them sequentially:
for coro in [asyncio.sleep(1) for _ in range(3)]: await coro
The code is executed for 3 seconds, despite the fact that all coroutines are created immediately (predictably), that is, each call is waiting for the end of the previous one.
For comparison, here is the code that runs in ~ 1 second (all functions are executed at the same time):
await asyncio.wait([asyncio.sleep(1) for _ in range(3)])
If there is a list of asynchronous methods, then to execute them sequentially, passing the result of previous calls to subsequent ones, you can again use a normal loop:
obj = C() for method in [Cm] * 3: obj = await method(obj)
In some cases, when all methods with one object work and their meaning is to return the next available result, you can use the async for cycle :
async for line in reader: print('>>>', line)
where reader is an object that implements __aiter__() .