python - Why does a class need __iter__() to return an iterator? -


why class need define __iter__() returning self, iterator of class?

class myclass:     def __init__(self):         self.state = 0      def __next__(self):         self.state += 1         if self.state > 4:             raise stopiteration         return self.state  myobj = myclass() in myobj:     print(i) 

console log:

traceback (most recent call last):    in myobj: typeerror: 'myclass' object not iterable 

the answer https://stackoverflow.com/a/9884259/4515198, says

an iterator object next (python 2) or __next__ (python 3) method.

the task of adding following:

def __iter__(self):    return self 

is return iterator, or object of class, defines __next__() method.

but, isn't task of returning object of myclass (which defines __next__() method) done __new__() method, when myclass instantiated in line myobj = myclass() ?

won't objects of class defining __next__() method, iterators themselves?

i have studied questions what use of returning self in __iter__ method? , build basic python iterator, still unable understand reason having __iter__() method returning self.

the answer question of why __iter__() method necessary for-loops start calling iter() on object iterator. why iterators themselved need __iter__() method work for-loops. after for calls iter(), calls __next__() on resulting iterator obtain value.

the rules creating iterables , iterators are:

1) iterables have __iter__() method returns iterator.

2) iterators have __next__() method returns value, updates state, , raises stopiteration when complete.

3) iterators have __iter__() method returns self. means iterators self-iterable.

the benefit of last rule iterators having __iter__() method returns self allows to pass around partially consumed iterators:

>>> s = 'hello world' >>> = iter(s) >>> next(it) 'h' >>> next(it) 'e' >>> list(it)     # doesn't start beginning ['l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'] 

here's example depends on iterators being self-iterable without restarting:

>>> s = 'hello world' >>> = iter(s) >>> list(zip(it, it)) [('h', 'e'), ('l', 'l'), ('o', ' '), ('w', 'o'), ('r', 'l')] 

notes:

1) alternative way make iterable supply __getitem__() method accepts consecutive indices , raises indexerror when complete. how str objects iterated in python 2.

2) objects files own iterator. means can call next() directly on file object. means files cannot have multiple, independent iterators (the file object has state tracking position within file).

3) iterator design pattern described above isn't python specific. general purpose design pattern many oop languages: https://en.wikipedia.org/wiki/iterator_pattern


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -