我要学python之生成器
admin
2023-07-19 09:43:06
0
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__())

相关内容

热门资讯

墨西哥男子在世界杯看台对韩国博... 【环球网报道 记者 张江平】综合韩国《首尔经济日报》等媒体17日报道,对于一名墨西哥男子在世界杯赛场...
中海油原副总经理袁光宇被判死缓 2026年6月17日,江苏省徐州市中级人民法院一审公开宣判中国海洋石油集团有限公司原党组成员、副总经...
沈阳一拉面店顾客带狗上桌吃饭,... 6月16日中午,有网友拍到辽宁省沈阳市的老四季拉面店沈辽东路店内,一名顾客带着宠物狗进店就餐,并将食...
国台办发言人:确定不问张凌赫了...   国台办发言人:确定不问张凌赫了哈?  【国台办发言人:确定不问张凌赫了哈?】6月17日消息,台媒...
中国刷锅神器丝瓜瓤现身旧金山,... “漫步旧金山街头,居然偶遇了熟悉的丝瓜瓤。”近日,有网友发布短视频称,在美国旧金山街头,看到了丝瓜瓤...
江苏省政府副秘书长徐华勤接受纪... 江苏省政府副秘书长徐华勤涉嫌严重违纪违法,主动投案,目前正接受江苏省纪委监委纪律审查和监察调查。
欧盟新一轮对俄制裁新增4家中企... 我驻欧盟使团发言人就欧盟新一轮对俄制裁新增制裁中方企业答记者问问:6月15日,欧盟公布新一轮对俄罗斯...
台北交通拥堵怎么办?沈伯洋称“... 海峡导报综合报道 民进党台北市长参选人沈伯洋近日接受亲绿媒体人郑弘仪专访,被问到怎么解决台北市内湖科...
17岁女生饮酒后投河身亡,父母... 17岁女生小A(化名)被男子刘某带去参加聚餐时喝了酒,后在被送回家到小区门口时,她下车投河身亡。事后...
外交部:中方对美以伊战事及其外... 【环球时报-环球网报道 记者 丁雅栀】6月17日,外交部发言人林剑主持例行记者会。会上有记者提问称,...