yield的作用
返回一个生成器
一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
generator的next()方法在python 2中为next(),但在python 3中为 __next__()
相当于一个return。不过return会终止函数,返回结果。yield会返回yield后的,但会保留运行环境。下次调用生成器并不会从函数的开始执行,只是接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束。
def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b      # 使用 yield
        # print b 
        a, b = b, a + b 
        n = n + 1
 
for n in fab(5): 
    print n

yield from

#!/usr/bin/env python

# -*- coding: utf-8 -*-if __name__ == '__main__':

    astr = "ABC"

    alist = [1, 2, 3]

    adict = {"name": "wangbm", "age": 18}

    # generate

    agen = (i for i in range(4, 8))

 

    def gen(*args, **kw):

        for item in args:

            yield from item

 

    new_list = gen(astr, alist, adict, agen)

    print(list(new_list))

    # ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
  • yield from 完全代替了内层的 for 循环。
  • yield from x 表达式对 x 对象所做的第一件事是,调用 iter(x),从中获取迭代器。因
    此,x 可以是任何可迭代的对象。
  • 在这个示例中使用 yield from代码读起来更顺畅,不过感觉更像是语法糖。
  • #coding=utf-8
    mygen=(x*x for x in range(3))
    for i in mygen:
        print(i)
    
    def num():
        for i in list(range(10,20)):
            yield i
    n=num()
    print(next(n))
    print(next(n))
    
    astr = "ABC"
    
    alist = [1, 2, 3]
    
    adict = {"name": "wangbm", "age": 18}
    
    # generate
    
    agen = (i for i in range(4, 8))
    
    
    
    def gen(*args, **kw):
    
        for item in args:
    
            yield from item
    
    
    
    new_list = gen(astr, alist,agen,adict)
    
    print(list(new_list))
    def gen1(*args,**kw):
        print(args)
        for item in args:
            for i in item:
                print(i)
    
    gen1(astr, alist,agen,adict)
    
    def fab(max): 
        n, a, b = 0, 0, 1 
        while n < max: 
            yield b      # 使用 yield
            print(a,b) 
            a = b
            b=a + b 
            n = n + 1
     
    for n in fab(5): 
        print(n)
    
    def square(n):
        print('generator')
        for i in range(n):
            yield i ** 2
    # for i  in square(9):
    #     print(i)
    print(type(square))
    print(dir(square(3)))
    
    gg=square(7)
    print(gg.__next__())
    
    # 包含yield的函数运行后,会返回一个生成器。
    # 生成器调用next()或__next__()时,相当于return ,返回yield后面的值,程序会停止并保留运行时上下文(及局部变量)。
    # 再次调用next()或__next__()时,从yield结束的地方开始运行,直到碰到下一个yield。
    
    def foo():
        print("starting...")
        while True:
            res = yield 4
            print("res:",res)
    g = foo()
    print(next(g))  #并没有执行赋值给res操作,现在执行右边,return出去了。
    print("*"*20)
    print(next(g))  #开始打印res,None
    print("*"*20)
    print(g.send(7))
    # 5.程序执行g.send(7),程序会从yield关键字那一行继续向下运行,send会把7这个值赋值给res变量
    
    # 6.由于send方法中包含next()方法,所以程序会继续向下运行执行print方法,然后再次进入while循环
    
    # 7.程序执行再次遇到yield关键字,yield会返回后面的值后,程序再次暂停,直到再次调用next方法或send方法。