二十二、生成器函数

生成器函数进阶

首先,先看一个实例:

def generator():
    print(123)
    content = yield 1
    print('generatorNum',num)
    print(456)
    yield 2
#生成一个生成器
g = generator()
#ret = g.send("函数") #调用send()函数取值,此时会报错,关于send()函数及报错的原因后面再说
#调用__next__()函数取值
ret = g.__next__() #结果为:输出123,ret或的值为1
#调用send()函数取值
ret = g.send("mmx") #结果为:输出generatorNum,mmx,456;ret获得的结果为2

send()函数: 从上面可以看到send()函数也可以用来获取生成器中的值,并且用其获取生成器中值的效果和next基本一致,不同的地方在于用send()函数获取下一个值的时候,给上一yield的位置传递一个数据,这个数据即为传给send()函数的参数。
注意: 从上面很容易看出,第一次使用生成器的时候,必须要用__next__()获取下一个值,第二次获取值的时候才可以使用send()方法;并且最后一个yield不能接收外部的值,如果最后一个yield确实还需要实现一些功能,可以按如下的样式来写:

def generator():
	功能代码块
	cont1 = yield 返回值  #第一个yield
	功能代码块
	cont2 = yield 返回值  #第二个yield
	功能代码块
	yield 返回值   #最后一个yield
	功能代码块
	yield         #这里不加返回值即可
生成器函数的实例

1、这是一个求平均数的例子,其功能是:第一次调用时,求0的平均数,第二次调用传入一个值,求0和这个值的平均数,第三次同样传入一个数,求着三个数的平均数,…,依次类推。

def avger():
    sum = 0
    count = 0
    avg = 0
    while 1:
        num = yield avg
        sum += num
        count += 1
        avg = sum/count
g = avger() #生成生成器
ret = g.__next__() #求得0的平均数0
ret = g.send(20) #求的0与20的平均数
ret = g.send(30) #求得0、20与30的平均数

2、带有装饰器的生成器示例——预激生成器
本例是对上一个例子的一个补充,在上例中,当生成器生成后,首次必须使用__next__()来进行一个初始化,然后才能用send传值,这里将用装饰器来装饰次函数,让第一次的__next__()自动执行。

#装饰器
def des(func):
    def inner(*args,**kwargs):
        g = func(*args,**kwargs)
        g.__next__() #自动调用__next__()
        return g
    return inner
#生成器
@des
def avger():
    sum = 0
    count = 0
    avg = 0
    while 1:
        num = yield avg
        sum += num
        count +=1
        avg = sum/count
#由于装饰器的作用,这次便可直接使用send()方法
g = avger()
ret = g.send(20)
ret = g.send(30) #此时ret的结果为25.0
ret = g.send(40) #此时ret的结果为(40+20+30)/3

预激生成器 就是指的类似于本例中的这种生成器,不需要自己手动初始化,而使用装饰器来自动执行__next__()方法来激活。

yield from关键字

这个关键字后面跟的是一个容器,此关键字可以将容器中的所有值挨个取出来,具体的将在实例中展开:

def generater():
    a = 'abcd'
    b = '1234'
    yield from a#用在生成器当中,从容器a中返回一个一个的值,
                #后面只能跟一个值
    yield from b
#上面的代码等价于:
def generater():
    a = 'abcdc'
    b = '12345'
    for i in a:
        yield i
    for j in b:
        yield j
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值