yield关键字一直困扰了我很久,一直也没有弄明白,现在将暂时理解的yield记录如下,供参考:

关键词:可迭代对象,生成器,迭代器

一、可迭代对象:

可迭代对象:可迭代对象是一个泛称,只要可以用for...in...处理的对象都可以称为可迭代对象。包括:列表(list)、元组(tuple)、字典(dict)、字符串(str)、文件(file)及迭代器和生成器。

二、迭代器:

迭代器:迭代器是一个对象,实现__iter__方法和__next__方法(只实现了__iter__方法的对象是可迭代的,并实现了__next__方法的对象是迭代器),迭代器通过调用__next__()方法获取下一个值;

自定义迭代器(实现__iter__()方法和__next__()方法)

class M(object):
    def __init__(self,max):
        self.max=max
        self.n=0
    def __iter__(self):
        return self
    def __next__(self):
        if self.n<self.max:
            self.n=self.n+1
            return self.n
        else:
            raise StopIteration  #一定要加上这一句,否则是无限循环了

m=M(5)
for i in m:
print(i)
输出结果:
1
2
3
4
5

三、生成器:

生成器:生成器是一个函数,内部实现了yield关键字的函数都可称为生成器。

生成器是特殊的迭代器。它不像list那样,将所有的数据都存储在内存中,那样占用极大的内存空间,而生成器每一次调用只返回一个数值,因此效率更高。

生成器的优点:效率高,速度快,不占内存,优选使用生成器而不是list之类的可迭代对象

生成器生成有两种个方式:

1.(x*2 for x in range(5))即可返回一个生成器

2.实现了yield关键字的函数。带有yield的函数就不再是一个普通的函数,而变成了一个生成器可以迭代了。

yield理解:

1.yield相当于普通函数中的return语句,yield语句右边即是其包含函数(生成器)要返回的值。

2.每次迭代,运行完yield语句后暂停(即将yield右侧值返回),yield下一行语句等到下一次迭代再运行。

3.生成器可以迭代的原因是内部实现了一个__next()__方法,每次迭代,运行一次__next__()方法,直到捕获到异常为止。

4.迭代三种方式:for..in..循环;调用__next__()方法;调用send(msg)方法

代码示例(来源于网络,https://www.jianshu.com/p/d09778f4e055):

# encoding:UTF-8  
def yield_test(n):
for i in range(n):
yield call(i)
print("i=", i)
# 做一些其它的事情
print("do something.")
print("end.")
def call(i):
return i * 2 # 使用for循环
for i in yield_test(5):
print(i, ",")
#或者使用__next__()方法
for i in range(5):
yield_test(5).__next__() 输出结果:
>>>   
0 ,
i= 0
2 ,
i= 1
4 ,
i= 2
6 ,
i= 3
8 ,
i= 4
do something.
end.
>>>
执行过程原理:
生成器对象每次迭代,只返回一个数据(由yield返回),而这每次迭代就发生在for i in yield_test(5):的时候,这条语句的内部是调用了next(yield_test)函数。由于每次迭代只返回一个值,生成器内部只执行一次,因此对于生成器内的五次for循环,需要五次迭代才能完成。
我们在分析运行过程时,要将迭代器看成一个蹦出值的机器,只有在通电(迭代)的时候机器才会运转一次,返回一个值,不要将生成器想的太复杂了。既然叫它生成器,它肯定是能够生产东西的机器,这个东西就是yield返回的那个数据。

yield生成器的__next__()方法与send(msg)方法

参考文章:

1.为什么yield生成器第一次不能用send发送数据

2.python的迭代器为什么一定要实现__iter__方法?

由于生成器是惰性运行,即每次迭代只运行一次。我们定义一个迭代器:

def h():
print('wen chuan')
m=yield 5#将yield 5当作一个整体,赋值给m
print(m)
n=yield 12
print('together') if __name__=='__main__':
g=h()#生成一个生成器
print(type(g))#验证g的类型,打印值为<class 'generator'>
g.__next__()#迭代一次
print(g.send('haha'))
打印结果:
<class 'generator'>
wen chuan
haha
12
执行过程: 执行g.__next__(),程序运行到yield 5,将5返回,然后暂停。执行g.send('haha'),将yield 5当作整体,将‘haha'赋值给这个整体,并赋值给m,打印m值,再次运行到yield 12,将12返回。
因此,send()函数除了具有__next__()一模一样的迭代作用外,还能够给jield x整体赋值。

python中的yield关键字的更多相关文章

  1. 解析Python中的yield关键字

    前言 python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield.有效利用生成器这个工具可以有效地节约系统资源,避免不必要的内存占用. 一段代码 def fun(): for i i ...

  2. 深入理解python中的yield关键字

    想必大家都看过这样的代码: 上面的这段代码会计算0-9的平方并打印出来. 那么问题来了,这段代码和我们要说的东西有什么区别呢? 这里的关键字,yield,我在前面的文章里已经发过了.那么yield是什 ...

  3. (转) Python Generators(生成器)——yield关键字

    http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...

  4. Python:笔记(7)——yield关键字

    Python:笔记(7)——yield关键字 yield与生成器 所谓生成器是一个函数,它可以生成一个值的序列,以便在迭代中使用.函数使用yield关键字可以定义生成器对象. 一个例子 我们调用该函数 ...

  5. 关于Python中的yield

    关于Python中的yield   在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,f ...

  6. 深入理解Python中的yield和send

    send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互. 但是需要注意,在一个生成器对象没有执行next方法之前,由 ...

  7. Python中所有的关键字

    在python中若想查询python中有哪些关键字可以先导入keyword模块 import keyword #导入关键字模块print(keyword.kwlist) #查询所有关键字 查询结果: ...

  8. Python中的yield生成器的简单介绍

    Python yield 使用浅析(整理自:廖 雪峰, 软件工程师, HP 2012 年 11 月 22 日 ) 初学 Python 的开发者经常会发现很多 Python 函数中用到了 yield 关 ...

  9. Python中的yield和Generators(生成器)

    本文目的 解释yield关键字到底是什么,为什么它是有用的,以及如何来使用它. 协程与子例程 我们调用一个普通的Python函数时,一般是从函数的第一行代码开始执行,结束于return语句.异常或者函 ...

随机推荐

  1. 【Caffe】caffemodel的大小计算(转载)

    看到一篇将如何计算caffemodel大小的blog,感觉对理解模型大小很有帮助. 原文地址:http://blog.csdn.net/u014696921/article/details/52413 ...

  2. unittest 结合 ddt

    数据驱动测试ddt,使用的重点: 1.@ddt.ddt2.@ddt.data(*zip(range(10),range(10,20)))       注意一定要带* 3.@ddt.unpack # c ...

  3. Java多线程编程总结一:多线程基本概念

    Java多线程编程总结一 – 初识多线程 进程.多进程.线程.多线程的概念 进程(process):CPU的执行路径.通俗的说就是系统中正在运行的程序.比如我们打开了浏览器.QQ等等,这些程序一旦被打 ...

  4. 全文检索引擎Solr的配置

    描述: 在Linux环境下实现高速的全文检索 一.当前环境: CentOS (Linux) 6.3 64 bit 二.所需软件 1.Java的JDK Java jdk 1.7.0[注意:solr5.x ...

  5. Linux服务器性能日志收集和分析脚本(转)

    最近老大要求分析服务器的性能数据,找到服务器运行的性能瓶颈,结果花了两天时间,写了两个脚本可以生成日志并可以进行数据提取,最终生成数据可以放到excel生成报表.过程中也学到了不少shell编程技术. ...

  6. EasyNVR无插件直播服务器软件使用详情功能-通道配置Excel

    背景需求 使用EasyNVR的用户都有知道,由于EasyNVR是将设备与EasyNVR的通道进行绑定的,因此EasyNVR是通过手动的通道配置来进行设备接入的,这样可以做到将设备的和通道对应的接入.但 ...

  7. 《Java线程池》:任务拒绝策略

    在没有分析线程池原理之前先来分析下为什么有任务拒绝的情况发生. 这里先假设一个前提:线程池有一个任务队列,用于缓存所有待处理的任务,正在处理的任务将从任务队列中移除.因此在任务队列长度有限的情况下就会 ...

  8. nginx学习之进程控制篇(三)

    1. 进程 nginx有一个master进程和一个或多个工作进程. master process worker process or master process worker process wor ...

  9. react-native 使用 antd-mobile-rn UI进行开发app

    1.创建 react-native 项目 react-native init app03 2.安装组件 npm install antd-mobile-rn --save 3.配置按需加载 npm i ...

  10. [DBNETLIB][ConnectionOpen(Connect()).]SQL Server 不存在或拒绝访问 数据库错误 解决办法总结

    连接数据库报错:“数据库异常:[DBNETLIB] [ConnectionOpen(Connenct()).] Sqlserver 不存在或拒绝访问” 原因: 1.查看是不是没有在数据库中添加数据库服 ...