温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

我要学python之生成器

发布时间:2020-06-08 12:55:55 来源:网络 阅读:273 作者:刺激乐天派 栏目:编程语言
from collections import Iterable

# 模拟取款
def cash_atm(totalmoney):
    while totalmoney>0:
        print("=======(可取金额:%s )=======" % totalmoney)
        totalmoney -= 100
        yield 100
        print("=======(    余额:%s )=======" % totalmoney)

atm = cash_atm(1000)
# 查看atm是个啥,是一个generator
print(type(atm))
# 判断atm是否可迭代
print(isinstance(atm, Iterable))
# 获取100现金
print(atm.__next__())
# 消费金额
print("买了本书把钱花完了...")
# 我想去买个礼物给女朋友,可没有钱了再去取钱
print(atm.__next__())
'''
定义:如果一个函数返回的是一个迭代器,那么这个函数就是生成器
那么如果一个函数要返回一个迭代器则需要使用yield语法,
该函数就可以返回一个迭代器
'''

分析:上面的cash_atm是一个生成器,它调用时返回一个迭代器,根据迭代器的特性,我们只能往下走,不能往回退,上面比较特殊的地方就是:每次请求执行atm的next时,都能够从上一次后面继续往下走,而这个关键在于yield语法,yield是能够跳出当前函数,并且保存执行的状态,下一次调用next时,可以从保存状态继续往下走。

应用分析:
这个生成器有什么应用场景呢?比如说:如果一个操作需要花费很长时间,如果是串行执行的,那么就必须等待操作执行完才可以去干其他的事情,那么这段时间内,你就处于被阻塞状态的,这是不理想的状态。最好的状态是什么呢?比如说我调用接口a,这个接口需要花费一段时间。最好的效果呢就是,我调用该接口,然后去做其他的事,一旦这个接口处理完成后通知我,我来处理这个结果返回的后续操作。这个就是异步操作,相当于我开一个线程去处理接口,接口处理完后会通知主线程处理。

场景应用:
模拟异步场景: 有一个餐馆,有一个厨师,有2名食客,食客点包子,厨师做包子,厨师做完后,食客开始吃。
这是一个生产消费模型,实现一个单线程的异步效果?

实现代码如下:

import time
# 生产者消费者模型:厨师生产者,食客消费者

# 消费者
def consumer(name):
    print("服务员给我[%s]上包子..."%name)
    while True:
        bz = yield
        print("%s,你好!包子[%s]来了!"%(name,bz))

# 生产者
def producer(name):
    c = consumer('A')
    c2 = consumer('B')
    c.__next__()
    c2.__next__()
    print("厨师[%s]开始做包子了..."%name)
    for i in range(10):
        time.sleep(1)
        print("我[%s]做好两个包子!"%name)
        c.send(i)
        c2.send(i)

producer('ckmike')

总结:
上面的代码是一个简单的单线程异步效果。生成器的作用非常大。消费者不需要等生产者把所有都准备好就可以把现有的消息消费掉,消费者只是接受消息信息号,把当前的信息处理掉,而生产者负责生成消息,并且信号发送给消费者。上面的效果可能我们还是有点模糊生成器有啥用。比如说现在我要获取一个斐波那契数列。我们没有必要把所有的值一次性加载到内存中,我们可以要一个拿一个(通过生成式实现),概念:这种一边循环一边计算的机制,称为生成器:generator。,与Linux下的cat命令类似,你不需要把大文件一次性加载到内存中,你只要获取部分到内存中,这样大大节省了内存。
菲波那切数列实现:


# 菲波那切数列
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

f=fib(10)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI