您好,登錄后才能下訂單哦!
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__())
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。