python - What's the advantage of using yield in __iter__()? -


what advantage of using generator(yield) inside __iter__() function? after reading through python cookbook understand "if want generator expose state user, don’t forget can implement class, putting generator function code in __iter__() method."

import io  class playyield:     def __init__(self,fp):         self.completefp = fp      def __iter__(self):         line in self.completefp:             if 'python' in line:                 yield line  if __name__ =='__main__':     io.open(r'k:\data\somefile.txt','r') fp:         playyieldobj = playyield(fp)         in playyieldobj:             print 

questions:

  1. what state means here?
  2. what advantage of using yield inside __iter__ () instead of using separate function yield?

without generator functions, have implement this, if want follow best practices:

in [7]: class iterablecontainer:    ...:     def __init__(self, data=(1,2,3,4,5)):    ...:         self.data = data    ...:     def __iter__(self):    ...:         return iterablecontaineriterator(self.data)    ...:  in [8]: class iterablecontaineriterator:    ...:     def __init__(self, data):    ...:         self.data = data    ...:         self._pos = 0    ...:     def __iter__(self):    ...:         return self    ...:     def __next__(self):    ...:         try:    ...:              item = self.data[self._pos]    ...:         except indexerror:    ...:             raise stopiteration    ...:         self._pos += 1    ...:         return item    ...:  in [9]: container = iterablecontainer()  in [10]: x in container:     ...:     print(x)     ...: 1 2 3 4 5 

of course, above example contrived, point. generators, can be:

in [11]: class iterablecontainer:     ...:     def __init__(self, data=(1,2,3,4,5)):     ...:         self.data = data     ...:     def __iter__(self):     ...:         x in self.data:     ...:             yield x     ...:     ...:  in [12]: list(iterablecontainer()) out[12]: [1, 2, 3, 4, 5] 

as state, well, it's - objects can have state, e.g. attributes. can manipulate state @ runtime. could following, although, highly inadvisable:

in [19]: class iterablecontaineriterator:     ...:     def __init__(self, data):     ...:         self.data = data     ...:         self._pos = 0     ...:     def __iter__(self):     ...:         return self     ...:     def __next__(self):     ...:         try:     ...:              item = self.data[self._pos]     ...:         except indexerror:     ...:             raise stopiteration     ...:         self._pos += 1     ...:         return item     ...:     def rewind(self):     ...:         self._pos = min(0, self._pos - 1)     ...:  in [20]: class iterablecontainer:     ...:     def __init__(self, data=(1,2,3,4,5)):     ...:         self.data = data     ...:     def __iter__(self):     ...:         return iterablecontaineriterator(self.data)     ...:  in [21]: container = iterablecontainer()  in [22]: = iter(container)  in [23]: next(it) out[23]: 1  in [24]: next(it) out[24]: 2  in [25]: it.rewind()  in [26]: next(it) out[26]: 1  in [27]: next(it) out[27]: 2  in [28]: next(it) out[28]: 3  in [29]: next(it) out[29]: 4  in [30]: next(it) out[30]: 5  in [31]: it.rewind()  in [32]: next(it) out[32]: 1 

Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -