Reference
http://docs.python.org/3/tutorial/classes.html#iterators
http://docs.python.org/3/tutorial/classes.html#generators
http://docs.python.org/3/tutorial/classes.html#generators
Iterator
這段程式
執行結果為
可以執行的原因是 range 回傳了一個可以 iterate 的物件,
讓 python 可以呼叫 "next" 取得下一個值.
如果想要自己實作一個能用 for iterate 的物件時,
只需要實作 __iter__ 與 __next__ 這兩個 function,
for 迴圈執行時 python 會自動執行這兩個 function.
我們只要在 __next__ 呼教時維持好物建的狀態即可.
通知 for 迴圈停止的方式是丟出一個 StopIteration 的 error
執行結果
for i in range(5): print(i)
執行結果為
0 1 2 3 4
可以執行的原因是 range 回傳了一個可以 iterate 的物件,
讓 python 可以呼叫 "next" 取得下一個值.
如果想要自己實作一個能用 for iterate 的物件時,
只需要實作 __iter__ 與 __next__ 這兩個 function,
for 迴圈執行時 python 會自動執行這兩個 function.
我們只要在 __next__ 呼教時維持好物建的狀態即可.
通知 for 迴圈停止的方式是丟出一個 StopIteration 的 error
class NumberIterator: def __init__(self, max): self.max = max self.current = 0 def __iter__(self): print('iter is called. max=',self.max) return self def __next__(self): print('next is called, current=', self.current, ', max=', self.max) if ( self.current == self.max ): raise StopIteration self.current += 1 return self.current it = NumberIterator(5) # "for" statement will call iter() of NumberIterator # so 'iter is called. max=' will be printed for i in it: print(i) #print 1 ~ 5 # there is no "for" statement, so 'iter is called. max=' won't be printed it = NumberIterator(4) print(next(it)) print(next(it)) print(next(it)) print(next(it)) print(next(it)) #StopIteration
執行結果
d:\workspace_python>python test.py iter is called. max= 5 next is called, current= 0 , max= 5 1 next is called, current= 1 , max= 5 2 next is called, current= 2 , max= 5 3 next is called, current= 3 , max= 5 4 next is called, current= 4 , max= 5 5 next is called, current= 5 , max= 5 next is called, current= 0 , max= 4 1 next is called, current= 1 , max= 4 2 next is called, current= 2 , max= 4 3 next is called, current= 3 , max= 4 4 next is called, current= 4 , max= 4 Traceback (most recent call last): File "test.py", line 27, inprint(next(it)) #StopIteration File "test.py", line 11, in __next__ raise StopIteration StopIteration
yield (iterator generator)
神奇的 yield, 這個 statement 是出現在 function 裡面,
讓程式先回傳, 但 function 內的狀態保持不變,
等下次程式的 __next__ 被呼叫時, 程式會從 yield 之後的碼繼續執行.
執行結果
def test_yield(): i = 0 print('before the first yield',i) yield i print('after the first yield',i) i += 1 print('before the second yield',i) yield i print('after the second yield',i) i += 1 for i in range(3): print('before yield in for stmt') yield i**2 print('after yield in for stmt') for i in test_yield(): print(i)
執行結果
d:\workspace_python>python test.py before the first yield 0 0 after the first yield 0 before the second yield 1 1 after the second yield 1 before yield in for stmt 0 after yield in for stmt before yield in for stmt 1 after yield in for stmt before yield in for stmt 4 after yield in for stmt
沒有留言:
張貼留言