Let's take a look. If you encounter an object, how can you tell if it is one of these three types:
1 from Import Generatortype 2 from Import iterable, Iterator 3 4 isinstance (xx, Generatortype) 5 isinstance (xx, iterable) 6 isinstance (xx, Iterator)
Builder object:
The generator is a function built with the yield keyword that returns a generator object and is also a iterator object because it implements the __iter__ and next methods
def Gene (k): ... for inch xrange (0, K): ... yield I ... in[5]: GE = gene (6) in[6]: type (GE) out[6]: generatorin[8]: Dir (GE) out[ 8]: [...,'__iter__'next', ...] in[9]: Isinstance (GE, collections. Iterator) out[9]: True
One feature of the generator is that it can only be used once
IN[11]: forIinchGE: ...PrintI ... 012345in[12]: Ge.next () Traceback (most recent call last): File"/usr/lib/python2.7/dist-packages/ipython/core/interactiveshell.py", Line 2820,inchRun_codeexecCode_objinchSelf.user_global_ns, Self.user_ns File"<ipython-input-12-b9172cd6050f>", Line 1,inch<module>ge.next ()stopiteration
Iterator object:
Implements the object of the __iter__ and __next__ methods.
__ITER__ returns an instance as the end-use iterator object--for...in ... When the statement is initialized, the next method is the one that is called each time the iterator object is iterated over each subsequent iteration
classCounter (object):def __init__(self, Low, high): Self.current=Low Self.high= Highdef __iter__(self): #'Returns itself as an iterator object' return Selfdef Next(self): #'Returns the next value till current was lower than high' ifSelf.current >Self.high:RaisestopiterationElse: Self.current+ = 1returnSelf.current-1
>>> c = counter ( Span class= "Mi" >5,10) >>> for i in c: ... Span class= "K" >print (iend=< Span class= "S1" > ") ... 5 6 7 8 9
>>> for I in C:
... pritn i
...
# No output
>>> c.next ()
Traceback (most recent): File "<ipython-input-12-b9172cd6050f>" c.next () Stopiteration
Objects that can be iterated:
An iterative object is used for for...in ... of the Loop
Different from the above two, it needs to be able to for...in multiple times ... Use
To write an iterative object through generator:
Write __iter__ as a generator function. Attention for...in ... When initializing the call __iter__ function makes the counter low, and then executes the yield affected area of the "1", unless the next time to execute the for...in ... The statement is called to the counter initialization sentence, which also implements the reuse. However, one problem is that counter instances are neither generator nor iterator objects at this time. So it can't call the next method.
classCounter (object):def __init__(self, Low, high): Self.low=Low Self.high= Highdef __iter__(self): counter=Self.low whileSelf.high >=Counter:yieldCounter Counter+ = 1obj= Counter (5, 10)Printisinstance (obj, Iterator)Printisinstance (obj, Generatortype)Printtype (obj) forIinchobj:PrintI
Obj.next ()
False
False
<class ' __main__. Counter ' >
5
6
7
8
9
10
Traceback (most recent):
File "/home/pd/..."
Obj.next ()
Attributeerror: ' Counter ' object has no attribute ' next '
Note "1":
In [1]:defGener (k): ... ..:Print "====initial====" ...: forIinchRange (0, K): ....:Print "before yield" ...: yieldI ...:Print "After yield" ...: Print "*****end******" ...: in [2]: G = Gener (3) in [3]: forIinchg: ...:Printg ...: ====initial====beforeyield<generator Object Gener at 0x7fbc8d15e870> Afteryieldbeforeyield<generator Object Gener at 0x7fbc8d15e870> Afteryieldbeforeyield<generator Object Gener at 0x7fbc8d15e870> Afteryieldend******
Reference:
Http://pymbook.readthedocs.io/en/latest/igd.html
Python in generator, iterator, Iterabel