本节内容

1、概述

2、生成器执行原理

3、send()和__next__()方法的区别

4、yield实现并行效果

一、概述

  之前只是介绍生成器,那有些同学就说了,这个生成器除了能节省资源,提高工作效率,但是我们再哪些场景下可以用呢?在哪些地方可以体现出它的价值呢?下面我们来逐一解答这些疑问。

二、生成器执行原理

1、执行原理

1
2
3
4
5
6
7
8
9
10
11
12
13
def consumer(name):
    print("%s 准备吃包子啦!"%name)
 
    while True:
        baozi = yield
 
        print("包子[%s]来了,被[%s]吃了"%(baozi,name))
 
= consumer("zhangqigao")
c.__next__()
 
#输出
zhangqigao 准备吃包子啦!

如果我再加一个__next__()方法会有什么效果?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def consumer(name):
    print("%s 准备吃包子啦!"%name)
 
    while True:
        baozi = yield
 
        print("包子[%s]来了,被[%s]吃了"%(baozi,name))
 
= consumer("zhangqigao")
c.__next__()
c.__next__()
 
#输出
zhangqigao 准备吃包子啦!
包子[None]来了,被[zhangqigao]吃了

很明显,第一种情况没有执行"print("包子[%s]来了,被[%s]吃了"%(baozi,name))",这段代码,接下来我们就来调试一下。

2、调试

第一步:生成一个生成器

第二步:执行第一个__next__()方法进入函数,执行到yield时中断,把返回值返回给baozi这个变量:

第三步:开始执行下面的程序,也就执行到了第二个__next__()方法,直接跳转到yield这边,继续上一次的中断往下执行,这样就执行了yield下面的程序,当再次执行到yield关键字时,则继续中断,并且把返回值赋给baozi关键字,如果下面没有其他程序,则程序结束。

小结:

  1. 用yield做生成器,你想把什么返回到外面,你就把yield关键字放在那里。
  2. yield其实是保留了函数的中断状态,返回当前的值。
  3. 如果yield没有返回值,就返回一个空值None

三、send()和__next__()方法的区别

1、send()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def consumer(name):
    print("%s 准备吃包子啦!"%name)
 
    while True:
        baozi = yield
 
        print("包子[%s]来了,被[%s]吃了"%(baozi,name))
 
= consumer("zhangqigao")
c.__next__()  #不使用__next__()方法会报错
b1 = "肉松馅"
c.send(b1)   #调用yield,同时给yield传一个值
b2 = "韭菜馅"
c.send(b2)
 
#输出
zhangqigao 准备吃包子啦!
包子[肉松馅]来了,被[zhangqigao]吃了
包子[韭菜馅]来了,被[zhangqigao]吃了

从上面可以看出send()和__next__()方法的区别:

  1. __next__()只是调用这个yield,也可以说成是唤醒yield,但是不不会给yield传值。
  2. send()调用这个yield或者说唤醒yield同时,也活给yield传一个值。
  3. 使用send()函数之前必须使用__next__(),因为先要中断,当第二次调用时,才可传值。

为什么给消费者传值时,必须先执行__next__()方法?

因为如果不执行一个__next__()方法,只是把函数变成一个生成器,你只有__next__()一下,才能走到第一个yield,然后就返回了,调用下一个send()传值时,才会发包子。

四、yield实现并行效果

yield还有一个更强大的功能,就是:单线程实现并发效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import time
 
def consumer(name):
    print("%s 准备吃包子啦!"%name)
 
    while True:
        baozi = yield
 
        print("包子[%s]来了,被[%s]吃了"%(baozi,name))
 
 
def producer(name):
    = consumer("A")
    c2 = consumer("B")
    c.__next__()
    c2.__next__()
    print("老子准备吃包子啦!")
    for in range(10):
        time.sleep(1)
        print("做了一个包子,分两半")
        c.send(i)
        c2.send(i)
 
producer("zhangqigao")

这个是生产者消费者模式,这个也就是后面协程的效果,这个我们后续再讲,先了解一下,生成器可以实现并发效果,极大的提高程序的运行效率。

函数和常用模块【day05】:生成器并行计算(五)的更多相关文章

  1. 函数和常用模块【day05】:生成器(四)

    本节内容 1.概述 2.列表生成式 3.生成器 4.函数实现生成器 5.生成器表达式 一.概述 我们在使用一组数据时,通常情况下会定义一个列表,然后循环里面的元素,但是你想过没有,如果你只需要使用列表 ...

  2. 函数和常用模块【day05】:迭代器(六)

    本节内容 1.简书 2.可迭代对象 3.迭代器 4.rang方法 5.总结 一.简述 我们经常使用for循环去遍历一些序列数据,但是我们有的时间发现for循环的效率很低,而且很占用了大量的硬件资源,但 ...

  3. 函数和常用模块【day06】:shelve模块(五)

    本节内容 1.简述 2.shelve概念 3.shelve模块使用 4.总结 一.简述 之前我们说不管是json也好,还是pickle也好,在python3中只能dump一次和load一次,不能dum ...

  4. 函数和常用模块【day05】:文件目录开发规范(七)

    本节内容 1.背景 2.设计目录结构的好处 3.关于readme的内容 4.关于requirements.txt和setup.py 5.关于配置文件的使用方法 一.背景 "设计项目目录结构& ...

  5. 函数和常用模块【day05】:不同目录间进行模块调用(八)

    本节内容 1.背景 2.函数功能解释 3.绝对路径和相对路径 4.不同目录间进行模块调用 一.背景 之前写了软件开发目录规范这篇博客,相信很多人都已经知道,我们在写程序时需要遵循一定的规范,不然,就算 ...

  6. 函数和常用模块【day05】:装饰器高潮(三)

    本节内容 1.概述 2.装饰器定义 3.装饰器定义 4.带参数的生成器 一.概述 我们之前介绍了大幅片的内容,感觉跟装饰器半毛钱关系都没有,其实不然,我们分别详细阐述了高阶函数和内置函数,下面我们就来 ...

  7. 函数和常用模块【day05】:装饰器前奏(一)

    本节内容 定义 原则 实现装饰器的储备知识 函数及变量 高阶函数 一.定义 1.装饰器:本质是函数. 2.功能:用来装饰其他函数,顾名思义就是,为其他的函数添加附件功能的. 二.原则 不能修改被装饰函 ...

  8. 函数和常用模块【day05】:装饰器前戏(二)

    本节内容 嵌套函数 局部作用域和全局作用域的访问顺序 一.嵌套函数 1.定义 在一个函数的函数体内,用def 去声明一个函数,而不是去调用其他函数,称为嵌套函数. 1 2 3 4 5 6 7 8 9 ...

  9. 函数和常用模块【day04】:递归(五)

    本节内容 作用域.局部和全局变量 递归 函数式编程 高阶函数和eval()函数 一.概述 在函数内部,可以调用其他函数.但是一个函数在内部调用自身,这个函数被称为递归函数. 二.简单介绍 那递归具体是 ...

随机推荐

  1. JQuery快速入门-事件与效果

    一.事件 事件绑定的方法有两种: 绑定到元素 查找元素后绑定事件 方法1:绑定到元素 <body> <p onclick='func1()'>点击我</p> < ...

  2. Java 面向对象之构造方法

    01构造方法引入 A:构造方法的引入 在开发中经常需要在创建对象的同时明确对象的属性值,比如员工入职公司就要明确他的姓名.年龄等属性信息. 那么,创建对象就要明确属性值,那怎么解决呢?也就是在创建对象 ...

  3. mui框架(一)

    1.界面初始化 初始化就是把一切程序设为默认状态,把没准备的准备好. mui框架将很多功能配置都集中在mui.init方法中,要使用某项功能,只需要在mui.init方法中完成对应参数配置即可,目前支 ...

  4. hadoop-lzo 安装配置

           在hive中要想使用lzo的格式,需要配置安装好lzo工具并且在hadoop的core-site.xml与mapred-site.xml中配置相应的配置 一.编译安装lzo与lzop 在 ...

  5. Estimation And Gain

    Estimation: Almost every is spent on ergod the text and build the dictionary. Gains: I have never us ...

  6. 《Linux内核设计与实现》学习记录一

    chapter1 Linux内核简介 前言:Unix是一个具有相似应用程序编程接口(API)并且基于相似设计理念的操作系统家族. 1.1 Unix的历史 1.Unix演化版实现了任务管理.换页机制.T ...

  7. C#使用结构体,输入5个人的学号,姓名,分数,按照成绩高低排列打印出来

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. vm15安装esxi6.0

    vmware 15安装esxi6.0时发现出现没有硬盘选择,导致无法安装 在vm12上安装正常 经过测试 1.需要在虚拟机硬件兼容性上选择12.x 2.版本也要选6.0,不要选6.X 其次,esxi要 ...

  9. Beta 冲刺 七

    团队成员 051601135 岳冠宇 031602629 刘意晗 031602248 郑智文 031602330 苏芳锃 031602234 王淇 项目进展 岳冠宇 昨天的困难 换了种方法写了搜索栏, ...

  10. postman 官方 test 脚本样例

    Test examples 样例来源: https://learning.getpostman.com/docs/postman/scripts/test_examples/ Test scripts ...