生成器是一種特殊的迭代器web
# 斐波那契數列 10 def create_num(all_num): a, b = 0, 1 current_num = 0 while current_num < all_num: # print(a) yield a # 若是一個函數中有yield語句,那麼這個就不在是函數,而是一個生成器的模板 a, b = b, a+b current_num += 1 # 調用的時候,發現有yield,不是調用函數,是建立一個生成器對象 obj = create_num(10) for i in obj: print(i)
# send def create_num(all_num): a, b = 0, 1 current_num = 0 while current_num < all_num: ret = yield a print(">>>ret>>>", ret) a, b = b, b+a current_num ++ 1 obj = create_num(10) # obj.send(None) # send通常不會放到第一次啓動生成器,若是非要這樣作 那麼傳遞None ret = next(obj) print(ret) # send裏面的數據會 傳遞給第5行,看成yield a 的結果,而後ret保存這個結果... # send的結果是下一次調用yield時,yield後面的值 ret = obj.send("haha") print(ret)
yield 實現多任務, 協程dom
# 協程,調用任務就像調用函數同樣,使用資源最少(進程 > 線程 > 協程) import time def task_1(): while True: print("---1---") time.sleep(0.1) yield def task_2(): while True: print("---2---") time.sleep(0.1) yield def main(): t1 = task_1() t2 = task_2() while True: next(t1) next(t2) if __name__ == '__main__': main() ## greenlet
# 安裝 pip install greenlet from greenlet import greenlet import time def test1(): while True: print("---a---") gr2.switch() time.sleep(0.5) def test2(): while True: print("bbbb") gr1.switch() time.sleep(0.5) gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch()
gevent的使用函數
# pip install gevent import gevent import time # 遇到耗時等待,自動切換任務 from gevent import monkey monkey.patch_all() # 耗時操做不用修改,能夠使用 time.sleep 完成耗時,而非 gevent.sleep def f1(n): for i in range(n): print(gevent.getcurrent(), i) time.sleep(0.5) # gevent.sleep(0.5) def f2(n): for i in range(n): print(gevent.getcurrent(), i) gevent.sleep(0.5) # gevent 的耗時操做 def f3(n): for i in range(n): print(gevent.getcurrent(), i) gevent.sleep(0.5) # g1 = gevent.spawn(f1, 5) # g2 = gevent.spawn(f2, 5) # g3 = gevent.spawn(f3, 5) # # g1.join() # g2.join() # g3.join() gevent.joinall([ gevent.spawn(f1, 5), gevent.spawn(f2, 5), gevent.spawn(f3, 5) ])
gevent 怎麼用?url
from gevent import monkey import gevent import random import time # 有耗時操做時須要 monkey.patch_all() # 將程序中用到的耗時操做的代碼,換爲gevent中本身實現的模塊 def coroutine_work(coroutine_name): for i in range(10): print(coroutine_name, i) time.sleep(random.random()) gevent.joinall([ gevent.spawn(coroutine_work, "work1"), gevent.spawn(coroutine_work, "work2") ])
import urllib.request import gevent from gevent import monkey monkey.patch_all() def downloader(url, name): req = urllib.request.urlopen(url) img_content = req.read() with open(name, "wb") as f: f.write(img_content) def main(): gevent.joinall([ gevent.spawn(downloader, "https://rpic.douyucdn.cn/asrpic/191118/1554733_6854945_7c3f7_2_1502.jpg/webpdy1", "1.jpg"), gevent.spawn(downloader, "https://rpic.douyucdn.cn/asrpic/191118/1282190_3853457_1abda_2_1450.jpg/webpdy1", "2.jpg") ]) if __name__ == '__main__': main()