## 2016年5月6日 星期五

### [ Python 文章收集 ] Python yield 使用淺析

Source From Here
Introduction

- 清單1. 簡單輸出斐波那契數列前 N 個數
1. def fab(N):
2.     n, a, b = 001
3.     while n < N:
4.         print b
5.         a, b = b, a + b
6.         n = n + 1

>>> fab(5)
1
1
2
3
5

1. def fab2(N):
2.     n, a, b = 001
3.     L = []
4.     while n < N:
5.         L.append(b)
6.         a, b = b, a + b
7.         n = n + 1
8.     return L

>>> for n in fab2(5):
... print n
...
1
1
2
3
5

1. for i in range(1000): pass

1. for i in xrange(1000): pass

1. class Fab(object):
2.
3.     def __init__(self, max):
4.         self.max = max
5.         self.n, self.a, self.b = 001
6.
7.     def __iter__(self):
8.         return self
9.
10.     def next(self):
11.         if self.n < self.max:
12.             r = self.b
13.             self.a, self.b = self.b, self.a + self.b
14.             self.n = self.n + 1
15.             return r
16.         raise StopIteration()
Fab 類通過 next() 不斷返回數列的下一個數，內存佔用始終為常數：
>>> for n in Fab(5):
... print n
...
1
1
2
3
5

1. def fab4(N):
2.     n, a, b = 001
3.     while n < N:
4.         yield b
5.         # print b
6.         a, b = b, a + b
7.         n = n + 1

>>> for n in fab4(5):
... print n
...
1
1
2
3
5

>>> f = fab4(5)
>>> f.__class__

>>> f.next()
1
>>> f.next()
1
>>> f.next()
2
>>> f.next()
3
>>> f.next()
5
>>> f.next()
Traceback (most recent call last):
File "", line 1, in
StopIteration

yield 的好處是顯而易見的，把一個函數改寫為一個 generator 就獲得了迭代能力，比起用類的實例保存狀態來計算下一個 next() 的值，不僅代碼簡潔，而且執行流程異常清晰。如何判斷一個函數是否是一個特殊的generator 函數？可以利用 isgeneratorfunction 判斷：

>>> from inspect import isgeneratorfunction
>>> isgeneratorfunction(fab4)
True

>>> import types
>>> isinstance(fab4, types.GeneratorType)
False
>>> isinstance(fab4(5), types.GeneratorType)
True

2.     BLOCK_SIZE = 1024
3.     with open(fpath, 'rb') as f:
4.         while True:
6.             if block:
7.                 yield block
8.             else:
9.                 return

Supplement
Python Gossip - 函式、類別與模組 - yield 產生器

## 關於我自己

Where there is a will, there is a way!