# 样例代码
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,",")

最近在scrapy爬虫方面接触了很多yield,找了很多网上的资料,很多大神都给出了很透彻的理解方法。但是由于我是菜鸟一个,对于一些很专业的解释看得似懂非懂。于是乎找了一段代码,自己在pycharm中一步步调试,终于弄懂了yield的工作原理。

样例代码中定义了两个方法yield_test以及call,将会在接下来的迭代中调用。

首先,我们将一个参数“5”传进yield_test方法中,代码将会执行到以下步骤。

for i in range(n):

代码将会生产一个[0,1,2,3,4]的列表,将会在该列表中进行迭代,此时i=0,开始进行迭代

代码运行到

yield call(i)

时,将会将i=0传入到 call()方法中,返回一个运算结果"0"

接下来生成器yield将会执行一个类似return的操作,将i=0返回到

for i in yield_test(5):
    print(i,",")

中,此时将会执行 print(i,",")语句,在Console窗口输出

完成以上的结果输出之后,由于yield的机制,下一次迭代时,从上一次迭代遇到的yield后面的代码开始执行

此时代码将会返回到以下语句中继续迭代

print("i=",i)

Console窗口将会继续打印出第二条结果

执行完毕之后,将会继续在yield_test方法中进行第二次迭代

此时i的值将会由0变为1   PS:前面生成的列表就是[0,1,2,3,4],刚开始是0,下一次迭代就是1啦

yield将会重复进行迭代,将1传到call()方法,计算完成后返回到主循环里面继续输出  print(i,",")  然后在根据yield的特性返回到  print("i=",i)  输出到Console窗口中,以此类推。

总结,引用其他大神总结,yield的特性如下:

    1. 通常的for...in...循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字符串,文件。它可以是mylist = [1, 2, 3],也可以是mylist = [x*x for x in range(3)]。
      它的缺陷是所有数据都在内存中,如果有海量数据的话将会非常耗内存。
    2. 生成器是可以迭代的,但只可以读取它一次。因为用的时候才生成。比如 mygenerator = (x*x for x in range(3)),注意这里用到了(),它就不是数组,而上面的例子是[]。
    3. 我理解的生成器(generator)能够迭代的关键是它有一个next()方法,工作原理就是通过重复调用next()方法,直到捕获一个异常。可以用上面的mygenerator测试。
    4. 带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代,工作原理同上。
    5. yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码开始执行。
    6. 简要理解:yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始。
    7. 带有yield的函数不仅仅只用于for循环中,而且可用于某个函数的参数,只要这个函数的参数允许迭代参数。比如array.extend函数,它的原型是array.extend(iterable)。
    8. send(msg)与next()的区别在于send可以传递参数给yield表达式,这时传递的参数会作为yield表达式的值,而yield的参数是返回给调用者的值。——换句话说,就是send可以强行修改上一个yield表达式值。比如函数中有一个yield赋值,a = yield 5,第一次迭代到这里会返回5,a还没有赋值。第二次迭代时,使用.send(10),那么,就是强行修改yield 5表达式的值为10,本来是5的,那么a=10
    9. send(msg)与next()都有返回值,它们的返回值是当前迭代遇到yield时,yield后面表达式的值,其实就是当前迭代中yield后面的参数。
    10. 第一次调用时必须先next()或send(None),否则会报错,send后之所以为None是因为这时候没有上一个yield(根据第8条)。可以认为,next()等同于send(None)。

以上是个人对yield的一些个人简介,如有表达错误,希望指正。

其实很多看起来很难的东西,把它抄过来,然后在调试模式中一步一步地去观察代码的运行情况,观察变量的变化,这样对理解一样新事物会有很大的帮助(很显然是废话 = =!)

关于Python中yield的一些个人见解的更多相关文章

  1. [转]Python中yield的解释

    转自: http://python.jobbole.com/83610/ 本文作者: 伯乐在线 - wklken .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 翻译 来源于stackover ...

  2. Python中yield和yield from的用法

    yield python中yield的用法很像return,都是提供一个返回值,但是yield和return的最大区别在于,return一旦返回,则代码段执行结束,但是yield在返回值以后,会交出C ...

  3. Python Deque 模块使用详解,python中yield的用法详解

    Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...

  4. [翻译]Python中yield的解释

    问题: Python中yield关键字的作用是什么?它做了什么? 例如,我想理解以下代码 def node._get_child_candidates(self, distance, min_dist ...

  5. python中yield用法

    在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何 ...

  6. Python中yield深入理解

    众所周知,python中的yield有这样的用法: def test(alist): for i in alist: yield i 这样,这个test函数就变成了一个生成器,当每次调用的时候,就会自 ...

  7. python中yield的用法

    ---"在python中,当你定义一个函数,使用了yield关键字时,这个函数就是一个生成器" (也就是说,只要有yield这个词出现,你在用def定义函数的时候,系统默认这就不是 ...

  8. python中yield使用

    16.yield使用   列表推导与生成器表达式   当我们创建了一个列表的时候,就创建了一个可以迭代的对象: >>> squares=[n*n for n in range(3)] ...

  9. Python中yield函数浅析

    带有yield的函数在Python中被称之为generator(生成器),下面我们将使用斐波那契数列来举例说明下该函数:(环境是在Python3.x下)  如何生成斐波那契数列: 斐波那契(Fibon ...

随机推荐

  1. HTTP长连接、短连接使用及测试

    概念 HTTP短连接(非持久连接)是指,客户端和服务端进行一次HTTP请求/响应之后,就关闭连接.所以,下一次的HTTP请求/响应操作就需要重新建立连接. HTTP长连接(持久连接)是指,客户端和服务 ...

  2. AOJ/初等排序习题集

    ALDS1_1_D-MaximumProfit. Codes: //#define LOCAL #include <cstdio> #include <algorithm> u ...

  3. angularjs 路由模块

    1. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title& ...

  4. HDU_1009_FatMouse' Trade

    FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  5. OC点语法介绍和使用以及@property关键字

    使用"点语法" Person *p =[Person new]; //点语法 //对象.属性名 //注意,此时 (p.age)并不是直接方法实例对象 //而是xcode可能到点语法 ...

  6. 由于losf引起的pxc启动报错处理

    PXC主节点启动完成后,再启动node1,error日志报错: 2017-05-02T15:23:42.830888Z 0 [ERROR] WSREP: Failed to read 'ready & ...

  7. HttpClient和 HtmlParser实现爬虫

    网络爬虫技术 1       什么叫网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不 ...

  8. ng-options语法详解

    我们先看下options的这条语句 ng-options="value.id as value.label group by value.group for value in myOptio ...

  9. zabbix安装配置

    实验环境 主机名 操作系统版本 IP地址 安装软件 console CentOS 7.0 114.55.29.246 Httpd.Nginx.MySQL.Zabbix log1 CentOS 7.0 ...

  10. 腾讯IVWEB团队:前端 fetch 通信

    欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 作者:villainthr 文章摘自: 前端小吉米 随着前端异步的发展, XHR 这种耦合方式的书写不利于前端 ...