From the docs relative to async for syntax in Python 3.5, I gathered that it was introduced to iterate over an awaitable iterator.
There is something I don't get in the semantic equivalent that follow the description though:
iter = (ITER)
iter = type(iter).__aiter__(iter)
running = True
while running:
try:
TARGET = await type(iter).__anext__(iter)
except StopAsyncIteration:
running = False
else:
BLOCK
else:
BLOCK2
What is the line iter = type(iter).__aiter__(iter) doing? Why is it necessary?
Magic methods in python, e.g. __add__, are always looked up on the class. For example, len(foo) will actually call resolve to type(foo).__len__(foo). This means it will never use a foo.__len__ if __len__ is defined on foo.
Since __aiter__ is a magic method, it is thus always looked up as type(foo).__aiter__(foo).
Example for lookup:
class Thingy(object):
def __len__(self):
return 10
lengthy_thingy = Thingy()
lengthy_thingy.__len__ = lambda self: 20
print(len(lengthy_thingy)) # gives `10`
print(lengthy_thingy.__len__(lengthy_thingy)) # gives `20` instead
print(type(lengthy_thingy).__len__(lengthy_thingy)) # gives `10` as for using `len`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With