-1

Instances of some classes are iterable in Python, but have only dunder "iter()" method, not "next()".

class Vector2d:
    def __init__(self, x, y):
        self.x = float(x)
        self.y = float(y)
    def __iter__(self):
        return (i for i in (self.x, self.y))

v=Vector2d(1,2)
x1,x2=v 
print(x1,x2)
iv=iter(v)
print(next(iv))
print(next(iv))
jmakov
  • 7

1 Answers1

1

Your __iter__ method IS returning an object with a next function:

z = Vector2d(4, 5)

z_iter = z.__iter__()

print(type(z_iter))

for coord in z:
    print(coord)

# <type 'generator'>

It's this generator that's providing the next() func.

Here's a very silly re-write of your vector class:

class Vector2d:
    def __init__(self, x, y):
        self.x = float(x)
        self.y = float(y)
        self.index = 0

    def __iter__(self):
        return self

    def next(self):
        if self.index < 2:
            ret = [self.x, self.y][self.index]
            self.index += 1
            return ret
        else:
            raise StopIteration()


v = Vector2d(1, 2)
for coord in v:
    print(coord)

This does actually provide native iteration functionality - again, in a very silly way.

edit: replace next() with __next__() in older python 2.x versions. I forget which exactly.

Danielle M.
  • 3,607
  • 1
  • 14
  • 31
  • 1
    I upvoted, but I would just point out with your edit, that normally you wouldn't make a container its own iterator. So, following best practices, you would have `ContainerClass` and `ContainerIterator`, which is lots of boilerplate, which is *one great* thing about generators, they lets us make iterators in a handy way, not requiring a seperate class! I elaborated on that in [this answer](https://stackoverflow.com/questions/45685538/whats-the-advantage-of-using-yield-in-iter/45685692#45685692) – juanpa.arrivillaga Mar 29 '19 at 22:02