分享

Python编程之从生成器使用入门协程

 xiaoyimin 2019-06-02

从今天开始,我们将开始进入Python的难点,那就是协程。

为了写明白协程的知识点,我查阅了网上的很多相关资料。发现很难有一个讲得系统,讲得全面的文章,导致我们在学习的时候,往往半知半解,学完还是一脸懵逼。

学习协程的第一门课程,是要认识生成器,有了生成器的基础,才能更好地理解协程。

如果你是新手,那么你应该知道迭代器,对生成器应该是比较陌生的吧。没关系,看完这系列文章,你也能从小白成功过渡为Ptyhon高手。

可迭代、迭代器、生成器

初学Python的时候,对于这三货真的是傻傻分不清。甚至还认为他们是等价的。

其实,他们是不一样的。

可迭代的对象,很好理解,我们很熟悉的:字符串,list,dict,tuple,deque等

为了验证我说的,需要借助collections.abc这个模块(Python2没有),使用isinstance来类别一个对象是否是可迭代的(Iterable),是否是迭代器(Iterator),是否是生成器(Generator)。

输出结果

从结果来看,这些可迭代对象都不是迭代器,也不是生成器。它们有一个共同点,就是它们都可以使用for来循环。这一点,大家都知道,我们就不去验证了。

扩展知识:

可迭代对象,是其内部实现了,__iter__ 这个魔术方法。

可以通过,dir方法来查看是否有__iter__来判断一个变量是否是可迭代的。

接下来是,迭代器。

对比可迭代对象,迭代器其实就只是多了一个函数而已。就是__next__,我们可以不再使用for循环来间断获取元素值。而可以直接使用next方法来实现。

迭代器,是在可迭代的基础上实现的。要创建一个迭代器,我们首先,得有一个可迭代对象。

现在就来看看,如何创建一个可迭代对象,并以可迭代对象为基础创建一个迭代器。

输出

如果上面的代码太多,也可以看这边,你更能理解。

接下来,是我们的重点,生成器。

生成器的概念在 Python 2.2 中首次出现,之所以引入生成器,是为了实现一个在计算下一个值时不需要浪费空间的结构。

前面我们说,迭代器,是在可迭代的基础上,加了一个next方法。

而生成器,则是在迭代器的基础上(可以用for循环,可以使用next),再实现了yield。

yield 是什么东西呢,它相当于我们函数里的return。在每次next,或者for遍历的时候,都会yield这里将新的值返回回去,并在这里阻塞,等待下一次的调用。正是由于这个机制,才使用生成器在Python编程中大放异彩。实现节省内存,实现异步编程。

如何创建一个生成器,主要有如下两种方法

使用列表生成式

实现yield的函数

可迭代对象和迭代器,是将所有的值都生成存放在内存中,而生成器则是需要元素才临时生成,节省时间,节省空间。

如何运行/激活生成器

由于生成器并不是一次生成所有元素,而是一次一次的执行返回,那么如何刺激生成器执行(或者说激活)呢?

激活主要有两个方法

使用next

使用generator.send(None)

分别看下例子,你就知道了。

输出

生成器的执行状态

生成器在其生命周期中,会有如下四个状态

GEN_CREATED # 等待开始执行

GEN_RUNNING # 解释器正在执行(只有在多线程应用中才能看到这个状态)

GEN_SUSPENDED # 在yield表达式处暂停

GEN_CLOSED # 执行结束

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多