# 代码
def fibonacci():
yield 1
yield 1
yield 2
yield 3
yield 5
yield 8
pass
for i in fibonacci():
print(i)
pass
# 输出
D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test01.py
1
1
2
3
5
8
Process finished with exit code 0
3.2.1 next函数
Python内置了next函数, 能够让生成器请求它的下一个值
简单示例
# 代码
def fibonacci():
numbers = []
while True:
if len(numbers) < 2:
numbers.append(1)
pass
else:
numbers.append(sum(numbers))
pass
yield numbers[-1]
pass
gen = fibonacci()
for i in range(1, 10):
print(next(gen))
# 输出
D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test02.py
1
1
2
4
8
16
32
64
128
Process finished with exit code 0
**输出**
```shell
D:\Software\Installed\Python\Python36\python.exe D:/workspace/Pycharm/PurePythonProject/Test04.py
Python版本信息: 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)]
[1, 2]
1
2
Traceback (most recent call last):
File "D:/workspace/Pycharm/PurePythonProject/Test04.py", line 17, in <module>
print(next(gen))
StopIteration: 4
Process finished with exit code 1
3.3 与生成器之间的交互
生成器协议提供了send方法, 以允许与生成器的反向沟通
简单示例
import sys
print("Python版本信息: ", sys.version)
def squares():
a = 1
b = 1
while True:
print('A: ', a, ' ', b)
response = yield a + b
print('B: ', a, ' ', b)
if response:
b = int(response)
else:
b += 1
print('C: ', a, ' ', b)
pass
sq = squares()
print(next(sq))
print(next(sq))
print(sq.send(7))
print(next(sq))
D:\workspace\Pycharm\PurePythonProject>python
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> r = range(0, 5)
>>> r
range(0, 5)
>>> next(r)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'range' object is not an iterator
>>> type(r)
<class 'range'>
>>> it = iter(r)
>>> it
<range_iterator object at 0x0000014A70D9AEF0>
>>> next(it)
0
>>> next(it)
1
>>> it.send(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'range_iterator' object has no attribute 'send'
语句for i in range(0, 5)之所以可以运行, 是因为range函数返回了一个迭代对象
D:\workspace\Pycharm\PurePythonProject>python
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> m = map(lambda x, y: x + y, [1, 2, 3], [4, 5])
>>> next(m)
5
>>> next(m)
7
>>> next(m)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
3.5.5 文件对象
可以利用生成器逐行读取文本文件内容
D:\workspace\Pycharm\PurePythonProject>cat lines.txt
line 1
line 2
line 3
line 4
line 5
D:\workspace\Pycharm\PurePythonProject>python
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('lines.txt')
>>> next(f)
'line 1\n'
>>> f.readline()
'line 2\n'
>>> next(f)
'line 3\n'
>>> f.readline()
'line 4\n'
>>> next(f)
'line 5\n'
>>> next(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> f.readline()
''