On Fri, Aug 26, 2016 at 6:55 PM, Kouli <d...@kou.li> wrote: > recently, I have discovered Python's coroutines and enjoyed the whole > asyncio system a lot. But I ask you to make me understand one thing in > Python's coroutines design: why do we have to use "await" (or "yield > from") in coroutines? Why can coroutines etc. not be used > _from_coroutines_ (designated by 'async def') by a simple call-like > syntax (i.e. without the 'await' keyword)?
Two reasons. One is that Python allows you to call any function and inspect its return value - async functions are no different, and they do return something. The other is that it makes yield points obvious. Consider this hypothetical function: async def get_user_data(id): await db.query("select name from users where id=?", (id,)) name = await db.fetchone()[0] # transaction handling elided return name Now, suppose we're trying to figure out what's going on. One good solid technique is what I call "IIDPIO debugging": If In Doubt, Print It Out. async def get_user_data(id): print("Starting g_u_d") q = db.query("select name from users where id=?", (id,)) print(q) await q f = db.fetchone()[0] print(f) name = await f # transaction handling still elided print("g_u_d: Returning %r" % name) return name It's completely obvious, here, that this function will call db.query, print stuff out, and then put itself on ice until the query's done, before attempting the fetch. If the call on the second line automatically put the function into waiting mode, this display would be impossible, and the wait points would be entirely implicit. (If you want implicit wait points, use threading, not async I/O.) It's also possible to wait for things that didn't come from function calls per se. For instance, the same database lookup could be implemented using an ORM, something like this: class Table: async def __getitem__(self, id): if id in self._cache: return self._cache[id] await db.query(...) data = await db.fetchone() self._cache[id] = self.make_object(...) return self._cache[id] Whether this is good code or not is up to you, but it's perfectly legal, and would be used as "users = Table(...); my_user = await users[123]". To allow that, Python absolutely has to allow arbitrary expressions to be waited on, not just function calls. Does that answer the question? ChrisA -- https://mail.python.org/mailman/listinfo/python-list