Python yield

今天旁边同事阿福拷问:说下python yield和c static的区别

我回复了一句:我不会c语言,拒绝回答

他回复了一个缺少引号的字符串:……

今晚就把这功课补齐

HP的一个软件工程师这么写道:yield的作用就是把一个函数编程一个generator,带有yield的函数不再是一个普通函数,python解释器会将其视为一个generator

果然大牛说话就比较专业,我等初学者俗人就需要进一步这么了解:生成器是一个特殊的函数,与函数的主要区别在于函数return a value,而生成器yield a value同事标记或者记忆point of the yield以便于在下次调用时从标记点恢复执行,yield使函数转换成生成器,而生成器反过来又返回迭代器

我的理解一个带有yield的函数就是一个generator,每当函数执行到yield时,函数就返回一个迭代值,而到下一次迭代,程序就从yield的下条语句继续执行,而函数中的一些本地局部变量就保持不变了

自己都说的迷迷糊糊,借用涛哥曾经最爱对我说的一句话:show me the code!手写个小例子:

#!/usr/bin/env python

import time

def fun():
    a = 0
    while True:
        yield a
        a += 1

f = fun()
while True:
    print f.next()
    time.sleep(1)

输出结果就是1秒递增1地逐行输出

0
1
2
3
4
5

可以通过print type(fun)和print type(fun())分别得到类型分别是<type ‘function’>和<type ‘generator’>,而上面next()就是generator的一个方法,具体是为了取值

实际上在执行到f=fun()这行,是不会打印任何信息的,就算你fun()函数刚开始加一条print ‘hello world’,依旧会是啥都没有,可见当你执行generator函数fun()的时候,仅仅是生成了一个对象,并没有执行里面的内容,直到通过netx()语句让他执行,而函数执行到yield就会相当于中断下,把yield的参数给你

整个过程就是:

第一次f.next(),立马才会执行fun(),到了yield a,返回一个0输出来,完事之后此时就好像中断暂停了一样,但是会记住上次返回时在函数体的位置(我的理解)

第二次f.next(),会从yield a下面一条语句开始执行,而且a保存的是上次返回时候的值,然后进行第二次迭代,直到又遇见了f.next()那么就重复第一次f.next()的动作,如此礼尚往来,不停保存a的值,递增打印出来

也就是函数直到遇见next()才会执行生成器,向生成器要一个数,到了yield语句,生成器把yield的参数给你,之后生成器就不往下继续执行;当你继续向生成器要下一个数的时候,他会从上次的状态开始执行,直到又碰见了yield语句,再次把参数给你,再次暂停;继续等你贪得无厌地索求,如此反复,直到退出,我理解的大概就这个意思吧~!

阿福同学要考我的另一个C语言的static就懒得码字了~!

发表回复