On 10/8/15, Steven D'Aprano <st...@pearwood.info> wrote: > > That's one solution, but it is certainly possible for the class to be > its own iterator, in which case it needs to follow two rules: > > (1) self.__next__() needs to return the next value, or raise > StopIteration; > > (2) self.__iter__() needs to return self; > > and of course like all dunder methods __next__ and __iter__ need to be > defined on the class itself, not on the instance.
Except this is generally a bad way to iterate a reiterable. Without a separate iterator, there's no simple way to maintain state for concurrent iterations. file types are an exception. A file is reiterable (i.e. by seeking back to 0), but the OS file pointer makes a file naturally an iterator. Thus getting concurrent iterations of a disk file requires separate file objects that have separate OS file pointers. FrozenDict.next is an example of what not to do: def next(self): try: value = self.__kwargs.items()[self.__counter][0] except IndexError: raise StopIteration self.__counter += 1 return value In Python 2 this iterates the dict's keys by creating a list of (key, value) tuples -- every time next() is called. In Python 3, you'd have to explicitly create the list using list(self.__kwargs.items()). The design also lacks support for concurrent iterations, and not even multiple iterations since __counter isn't reset in __iter__. The simple approach is to have __iter__ return an instance of the wrapped dict's iterator. There's no reason to reinvent the wheel. Plus in the non-frozen case, the built-in dict iterators are smart enough to raise an error when the dict is modified, since it's assumed that any modification to the hash table invalidates the iteration. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor