一.迭代器

什么是迭代器?迭代器是一个能够记住遍历的地位的对象。
迭代器对象从汇合的第一个元素开始拜访,直到所有的元素被拜访完完结,它只能往前进行,不能后退。

什么是可迭代(可迭代对象)?

  • 1.遵循了可迭代协定的对象
  • 2.可迭代协定

    • 实现iter()办法,并返回的Iterator对象自身
    • 实现next()办法,当next()办法被调用,返回下一个值,直到没有值能够拜访。

list、tuple等都是可迭代对象,咱们能够通过iter()函数获取这些可迭代对象的迭代器,之后应用next()函数来获取下一条数据。iter()函数实际上就是调用了__iter_

In [5]: list_demo = [i for i in range(10)]In [6]: iter_list = iter(list_de)In [7]: iter_list = iter(list_demo)In [8]: next(iter_list)Out[8]: 0In [9]: next(iter_list)Out[9]: 1In [10]: next(iter_list)Out[10]: 2

二.生成器

什么是生成器?
咱们应用列表时,列表是曾经定义好的数据,例如[1, 2, 3, 4, 5, 6, 7, 8],这个能够按照某种算法推算出后续元素,是否能够不创立整个列表,而是遍历循环时,依据算法推算出元素而后应用呢,这样就能够节俭大量空间,实现了这个需要的就是生成器(Generator),实质还是迭代器,然而非凡的迭代器。
生成器是一类非凡的迭代器。

生成器和一般函数的区别是应用yield,而不是return返回值。

  • 应用含推导式的()定义生成器
In [14]: list_demo = [i for i in range(10)]In [15]: type(list_demo)Out[15]: listIn [16]: generator_demo = (i for i in range(10))In [17]: type(generator_demo)Out[17]: generator
  • 应用函数来实现
def a():    for x in range(3):        print(x)        yieldm = a()for x in range(3):    next(m)

三.协程

协程不是过程,也不是线程,它是用户空间调度的实现的并发解决的形式。

它是python中另外一种实现多任务的形式,只不过比线程更小,占用更小执行单元。 为啥说它是一个执行单元,因为它自带CPU上下文。这样只有在适合的机会, 咱们能够把一个协程 切换到另一个协程。 只有这个过程中保留或复原 CPU上下文那么程序还是能够运行的。

协程是线程内实现调度,它不须要更多的线程,天然也没有多线程切换带来的开销。
协程是非抢占式调度,只有一个协程被动让出控制权,另一个协程才会被调度。
协程也不须要应用锁机制,因为是在同一个线程中执行。

  • 简略实现一个协程
def a():    for x in range(3):        print(x)        yielddef b():    for x in range(3):        print(x)        yieldm = a()n = b()for x in range(3):    next(m)    next(n)

在线程内通过生成器实现了调度,让两个函数简直都有执行,这样的调度不是操作系统的过程、线程实现的,而是用户本人设计的,这个就是协程。

  • greenlet 实现协程
from greenlet import greenletimport timedef test1():    while True:        print("---test1---")        g2.switch()        time.sleep(0.5)def test2():    while True:        print("---test2---")        g1.switch()        time.sleep(0.5)g1 = greenlet(test1)g2 = greenlet(test2)#切换到g1中运行g1.switch()
  • gevent比greenlet更加弱小,可能主动切换

示例1

import geventdef fun(n):    for x in range(n):        print(gevent.getcurrent(), x)        gevent.sleep(1)g1 = gevent.spawn(fun, 5)  # 第一个参数为传递的执行函数,第二个参数,是f的参数g2 = gevent.spawn(fun, 5)g3 = gevent.spawn(fun, 5)g1.join()g2.join()g3.join()

示例2

from gevent import monkeyimport geventimport randomimport timemonkey.patch_all()def coroutine_work(coroutine_name):    for i in range(10):        print(coroutine_name, i)        time.sleep(random.random())gevent.joinall([        gevent.spawn(coroutine_work, "work1"),        gevent.spawn(coroutine_work, "work2")])

示例3

from gevent import monkeyimport geventimport randomimport timefrom gevent.pool import Poolpool = Pool(5) # 限度发送协程数monkey.patch_all()#def coroutine_work(coroutine_name):    for i in range(10):        print(coroutine_name, i)        time.sleep(random.random())gevent.joinall([    pool.spawn(coroutine_work, coroutine_name='work1'),    pool.spawn(coroutine_work, coroutine_name='work2'),])