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高级语法)