In datatstructures.py, there is a method values()
:
def values(self):
"""Iterate over all values."""
for item in self:
yield item[0]
self
is an instance of the class; how can it be iterated over?
In datatstructures.py, there is a method values()
:
def values(self):
"""Iterate over all values."""
for item in self:
yield item[0]
self
is an instance of the class; how can it be iterated over?
The class which the given method belongs to extends ImmutableList
which is iterable, thus the method can iterate on the class.
Simple, it has to implement __iter__
method, e.g.
class Test:
def __iter__(self):
yield 1
yield 2
>>> instance = Test()
>>> for val in instance:
... print val
...
1
2
My question is not How to but rather How can (as in: how can it be possible)
self
refers to the actual tangible object you deal with, classes
are more like their interface (don't interpret this too strictly); if an instances' class defines a __iter__
(or __getitem__
) method they can be iterated over in a for
loop. PEP 234 deals with the semantics and implementation of iterators.
In your specific case the function is a generator which has nothing to do with the __iter__
method, it simply transforms the values
function to a generator in order to support iteration of the form:
for i in instance.values(): # do stuff
If the object doesn't define an __iter__
it won't be able to be iterated over, as an example:
class myfoo:
def func(self):
for i in range(10): yield i
f = myfoo()
The instance f
is now not iterable:
for i in f: print(i) # TypeError
On the other hand, we can use func
in a for
loop:
for i in f.func(): print(i, end=" ")
0 1 2 3 4 5 6 7 8 9
Changing func
to __iter__
changes the picture, now the instance f
is iterable:
class myfoo:
def __iter__(self):
for i in range(10): yield i
f = myfoo()
Iterating through f
is done intuitively with:
for i in f: print(i, end=" ")
0 1 2 3 4 5 6 7 8 9
Asking why, as in, how can this be possible is like asking why can strings be multiplied with "s" * 4
. This is the way things were implemented because it just made sense as a way of handling the common case of looping through the contents of a container. Don't overthink things, it isn't necessary.