多任务-协程之迭代器
1.什么是协程?
协程,又称微线程,纤程。英文名Coroutine。协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用。子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。
总的来说,协程是一种轻量级的执行方式
2.协程的好处,优点
(1)协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
(2)不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
3.面对多核CPU,如何利用起来呢?
那就是多进程+协程,这样就可以高效的利用多核CPU了
4.什么是迭代?
迭代是访问集合元素的一种方式,我们已经知道可以对list、tuple、str等类型的数据使用for...in...的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。
5.可迭代对象
可以利用for循环遍历然后从头到尾一一取出的对象,称为可迭代对象。然而,并不是所有的容器都可以作为可迭代对象。
6.什么是迭代器?
迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
7.如何判断对象是否可迭代?
可以使用 isinstance() 判断一个对象是否是 Iterable 对象
In [50]: from collections import Iterable In [51]: isinstance([], Iterable) Out[51]: True In [52]: isinstance({}, Iterable) Out[52]: True In [53]: isinstance('abc', Iterable) Out[53]: True In [54]: isinstance(mylist, Iterable) Out[54]: False In [55]: isinstance(100, Iterable) Out[55]: False
8.可迭代对象的本质是什么?
接触到了可迭代对象,不免会有这么一个疑问,为什么同样是容器,有的容器支持迭代,有的却不支持迭代呢?这中间是否存在一种运行机制?
首先,对可迭代对象进行一次剖析。举个例子
列表[ ] ,是一种可迭代对象,使用for循环遍历列表时,可以从头到尾进行迭代,只有当列表中的所有数据都被迭代完成时,才会被停下。其实,在每一次迭代中,都有一种神秘的介质在帮助迭代,帮助返回下一条数据,在这里,称这种介质为迭代器(Iterator)
可迭代对象的本质也就是提供这样的一种介质,能够提供然后帮助进行遍历使用,就是可迭代对象。不能够提供,就不是可迭代对象。
9.可迭代对象如何支持迭代?
可迭代对象通过__iter__
方法向我们提供一个迭代器,我们在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据。那么也就是说,一个具备了__iter__
方法的对象,就是一个可迭代对象。
10.iter()函数、next()函数
list、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的__iter__
方法。
注意,当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不用再执行next()函数了。
11.迭代器Iterator
迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的__next__
方法(Python3中是对象的__next__
方法,Python2中是对象的next()方法)。所以,我们要想构造一个迭代器,就要实现它的__next__
方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__
方法,而__iter__
方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__
方法返回自身即可。