生成器的本质就是迭代器。

生成器包括两种:生成器函数和生成器表达式

1.生成器函数

一个包含yield关键字的函数就是一个生成器函数。并且yield不能和return共用,并且yield只能用在函数内。

 

(1).生成器函数执行之后会得到一个生成器作为返回值,并不会执行函数体。

(2).执行了__next__()方法之后才会执行函数体,并且获得返回值。

(3).next()内置方法,内部调用生成器函数的__next__()方法。

(3).yield和return相同的是可以返回值,但是不同的是yield 不会结束函数

 

练习1:创建一个生成器,并且调用

# 注意调用生成器,函数体是不会执行的,会返回一个生成器对象
def generator():
    print('xxxx')
    yield


ret = generator()  # 返回一个生成器对象

print(ret)  # 返回生成器对象的地址         <generator object generator at 
                                    0x0000000002754938>


ret.__next__()  # 调用__next__ 方法执行函数体,遇到yield停止    xxxx

ret.__next__()  # 报错,因为没有遇到yield

 

练习2:创建一个生成器,并且设置返回值

def generator():
    print('xxxx')
    yield 1


ret = generator()  # 返回一个生成器对象
a = next(ret)  # 调用__next__方法   xxxx 实际yield返回的1 已经有了,只是需要变量来承
                                          接
# print(a)      # 1    返回yield 的值

练习3:创建生成器,定义多个yield 值,

def generator():
    print('xxxx')
    yield 1
    print('oooo')
    yield 2


ret = generator()  # 返回一个生成器对象
a = next(ret)  # 调用__next__方法     xxxx
print(a)  # 1
a = next(ret)
print(a)  # 2

练习4:创建生成器,生成200万桶康师傅方便面。

def ksf():
    for i in range(2000000):
        yield '正在生成第%s桶方便面' % i


ret = ksf()
for i in ret:
    print(i)

2.send()

send 获取下一个值的效果和next()基本一致,只是在获取下一个值的时候,给上一yield的位置传递一个数据

使用send的注意事项

(1).第一次使用生成器的时候 是用next获取下一个值

(2).最后一个yield不能接受外部的值

 

练习1:使用send()方法给yield传递参数

 

python gui生成器 python 生成器原理_python gui生成器

 

练习2.计算移动平均值

def func_avg():
    avg = 0  # 平均值
    totle = 0  # 总和
    get_num = 0  # 传递的数
    count = 1  # 传递值的个数

    while True:
        get_num = yield avg
        totle = totle + get_num
        avg = totle / count
        count += 1


fun = func_avg()
next(fun)
print(fun.send(10))    # 10.0
print(fun.send(20))    # 15.0
print(fun.send(30))    # 20.0

3. yield  from

yield from 循环遍历容器类型

 

练习1:使用for循环取出g1生成器中所有的值。

def gen1():

    for i in 'abc':
        yield i
    for j in range(4):
        yield j

g = gen1()
for k in g:
    print(k)

练习2:使用 yield from 遍历出可变数据类型中的数据。

def gen1():
    yield from 'abc'

    yield from range(4)


g = gen1()
for k in g:
    print(k)

4.生成器表达式

将列表表达式的[ ] 改成()即可

g = (i for i in range(10))
print(g)  # 返回的生成器地址
for j in g:
    print(j)