Python高级语法——协程/迭代器/生成器——学习心得笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python高级语法——协程/迭代器/生成器——学习心得笔记相关的知识,希望对你有一定的参考价值。
Python高级语法——协程——学习心得笔记
1. 迭代器
- 可迭代(Iterable): 直接作用于for循环的变量
- 迭代器(Iterator): 不但可以用于for循环,还可以被next调用
- list是典型的可迭代对象,但不是迭代器
- isinstance判断是否可迭代或者迭代器
- iter转换可迭代的为迭代器
- 看案例32_1
32_1
# 迭代器实例
# l是可迭代的,但不是迭代器
l = [i for i in range(10)]
for idx in l:
print(idx)
# range是个迭代器
for i in range(5):
print(i)
# isinstance判断是否可迭代或者迭代器
from collections import Iterable, Iterator
ll = [1, 2, 3, 4, 5]
print(isinstance(ll, Iterable))
print(isinstance(ll, Iterator))
# 字符串是否可迭代
s = "i love you, you love me"
print(isinstance(s, Iterable))
print(isinstance(s, Iterator))
# iter转换可迭代的为迭代器
ss = iter(s)
print(isinstance(ss, Iterable))
print(isinstance(ss, Iterator))
# 生成器
# 中括号就是列表生成器
# 小括号就是生成器
L= [x*x for x in range(5)]
g = (x*x for x in range(5))
print(L)
print(g)
print(type(L))
print(type(g))
# 函数案例
def odd():
print("Step 1")
print("Step 2")
print("Step 3")
return None
odd()
print(type(odd()))
2. 生成器
- generator:一边循环一边计算下一个元素的机制或者算法
- 每次调用都能生成出for循环需要的下一个元素
- 可以被next函数调用
- 如果达到最后一个后,爆出Stoplteration异常
- 看案例32_2
- 生成器案例
32-2
# 生成器案例,yield
def odd():
print("Step 1")
yield 1
print("Step 2")
yield 2
print("Step 3")
yield 3
# 调用生成器
# next调用函数,执行过的就不在执行,执行没有被执行的
# 先生成一个生成器g
# yield先调用函数执行语句,然后返回yield之后的值
g = odd()
one = next(g)
print(one)
two = next(g)
print(two)
# for循环调用生成器
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a+b
n += 1
return "Done"
# 生成一个生成器
g = fib(5)
for i in range(6):
rst = next(g)
print(rst)
for i in g:
print(i)
3. 协程
- 用yield实现
- 实现协程比较好的包:
- asyncio, tornado, gevent
- 从技术来讲:协程就是一个可以暂停执行的函数,或者可以理解成一个生成器
- 协程的实现:
- yield返回
- send调用
- 看实例32_3,32_4
32-3
# 协程案例
def simple_coroutine():
print("->start")
x = yield
print("->recived", x)
# 第一步生成一个协程
sc = simple_coroutine()
# 执行一个语句
print(111)
# 预激协程
next(sc)
print(222)
sc.send("Done over")
# 上述代码的执行步骤,参看视频协程的1小时23分钟前后
32-4
# 协程案例2
def simpel_coroutine(a):
print("start")
b = yield a
print("recived", a, b)
c = yield a + b
print("recived", a, b, c)
# 主程序,先生成一个协程
# 将5赋值给a
sc = simpel_coroutine(5)
# 预激协程,执行打印开始,执行yield,将a的值返回
# a返回的值是5,返回后赋值给aa,协程暂停
aa = next(sc)
# 打印出a的值5
print(aa)
# 继续执行协程,6赋值给b,接着执行打印语句
# 打印出5和6,然后执行yield,返回a+b的值
# 返回的值给bb,协程然后暂停
bb = sc.send(6)
print(bb)
# 类似,7赋值给c,然后执行打印,然后再执行没有了
# 所以返回一个StopIteration的错误
cc = sc.send(7)
print(cc)
- 协程终止
- 协程中未处理的异常会向上冒泡,传给next函数或者send方法的调用方(即触发协程的对象)
- 终止协程的一种方式:发送某个哨符值,让协程退出。内置的常量None和Ellipsis常作为哨符值
- yield from
- 调用协程为了得到返回值,协程必须正常终止
- 生成器正常终止发出StopIteration异常,异常对象的value属性保存返回值
- yield from从内部捕获StopIteration异常
- 看实例32_5
- 委派生成器
- 包含yield from表达式的生成器函数
- 委派生成器在yield form处暂停,调用方法可以直接将数据发给生成器
- 子生成器再把产出的值发送给调用方
- 子生成器在最后,解释器会抛出StopIteration,并且把返回值附加到异常对象上
32-5
# yield from案例
def gen():
for c in "AB":
yield c
# 先返回A,再返回B
print(list(gen()))
def gen_new():
yield from "AB"
# 直接返回A和B
print(list(gen_new()))
# 委派生成器
以上是关于Python高级语法——协程/迭代器/生成器——学习心得笔记的主要内容,如果未能解决你的问题,请参考以下文章