python實(shí)習(xí)總結(jié)(yeild,async,azwait和協(xié)程)
一、yield使用簡析
yield是一個生成器generator,返回一個interable對象。
該對象具有next()方法,可以通過next()查看接下來的元素是什么。
1.interable對象 ,可以遍歷的對象,如: list,str,tuple,dict,file,xrange等。
2.yield的作用是什么?只是循環(huán)里面的獲取中間變量的一個方法,把想要的變量每次使用yield保存起來直至循環(huán)結(jié)束,循環(huán)結(jié)束得到了一個generator對象
3.為什么使用yield?使用yield,一個函數(shù)改寫成generator,便具有了迭代的能力,比起用類的實(shí)例保存狀態(tài)計算下一個需要迭代的值,代碼更加簡潔,執(zhí)行流程十分簡單。
4.如何判斷yield的類型?
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b # 使用 yield
# print b
a, b = b, a + b
n = n + 1
for n in fab(5):
print n
fab不是generator,fab(5)是generator。
好比類的定義和類的實(shí)例的區(qū)別。
>>>import types >>> isinstance(fab, types.GeneratorType) False >>> isinstance(fab(5), types.GeneratorType) True
fab 是無法迭代的,而 fab(5) 是可迭代的。
>>>from collections import Iterable >>> isinstance(fab, Iterable) False >>> isinstance(fab(5), Iterable) True
5.yield在文件讀取的應(yīng)用?
如果字節(jié)使用read()讀取一個文件,會導(dǎo)致不可預(yù)測的內(nèi)存占用。好的方法是使用yield,固定長度的緩沖區(qū)來不斷讀取文件,生成讀文件的迭代的generator。
def read_file(fpath):
BLOCK_SIZE = 1024
with open(fpath, 'rb') as f:
while True:
block = f.read(BLOCK_SIZE)
if block:
yield block
else:
return
二、async和await的使用
1.什么是進(jìn)程、協(xié)程、異步?
- 協(xié)程是什么?
一種用戶級輕量級的線程,擁有自己的寄存器上下文和棧。
協(xié)程切換時候,將寄存器和棧保存在其他地方,當(dāng)返回的時候,恢復(fù)原先保存的寄存器上下文和棧。
- 為什么使用協(xié)程?
主流語言采用多線程并發(fā),線程相關(guān)的概念是搶占式多任務(wù),協(xié)程相關(guān)的協(xié)作式多任務(wù)。
不管是多進(jìn)程還是多線程,每次阻塞、切換陷入系統(tǒng)調(diào)用。
CPU跑操作系統(tǒng)的調(diào)度程序,調(diào)度程序決定運(yùn)行哪一個進(jìn)程(線程)。
線程非常小心的處理同步問題,而協(xié)程完全不存在這個問題。
對于CPU而言,多協(xié)程是單線程,CPU不會考慮調(diào)度、切換上下文,省去CPU的切換開銷。協(xié)程好于多線程的原因。
- 如何使用協(xié)程?
多進(jìn)程+協(xié)程下,避開了CPU切換的開銷,又能把多個CPU充分利用起來,這種方式對于數(shù)據(jù)量較大的爬蟲還有文件讀寫之類的效率提升是巨大的。
2.如何處理200W數(shù)量的url,把所有的url保存下來?
- 單進(jìn)程+單線程
- 單進(jìn)程+多線程:開十個線程,速度不能提高十倍。線程的切換是有開銷的,無能無限的創(chuàng)建線程。
- 多進(jìn)程+多線程:多進(jìn)程的每個進(jìn)程占用一個CPU,多線程一定程度上繞過了阻塞時間,所以相比單進(jìn)程的多線程效率更高。
- 協(xié)程
3.使用async的await和gather
- await接受一個協(xié)程列表,返回done、pending兩個列表。done是已經(jīng)完成的協(xié)程,pending是仍在跑的協(xié)程。通過.result()獲取完成的結(jié)果
- gather以gather(cro1, cro2, cro3, cro4…)的方式接受協(xié)程,返回的是一個結(jié)合了這么多個任務(wù)的協(xié)程。
async的使用:https://blog.csdn.net/qq_29785317/article/details/103294235
async def func1(num):
print('--func1 start--')
await asyncio.sleep(num)
print('--func1 done--')
return 'func1 ok'
async def func2(num):
print('--func2 start--')
await asyncio.sleep(num)
print('--func2 done--')
return 'func2 ok'
async def main():
task1 = asyncio.ensure_future(func1(3))
task2 = asyncio.ensure_future(func2(5))
tasks = [task1, task2]
res = await asyncio.gather(*tasks)
return res
# done, pending = await asyncio.wait(tasks)
# for t in done:
# print(t.result())
# print(done)
# print(pending)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
result = loop.run_until_complete(main())
print(result)
```python
--func1 start--
--func2 start--
--func1 done--
--func2 done--
['func1 ok', 'func2 ok']
三、協(xié)程的理解
1.協(xié)程的過程
協(xié)程中yield是控制流程的方式。
yield同接收器一樣,是一個生成器,需要先激活才能使用。
>>> def simple_corotine():
... print('---->coroutine started')
... x = yield #有接收值,所以同生成器一樣,需要先激活,使用next
... print('---->coroutine recvied:',x)
...
>>> my_coro = simple_corotine()
>>> my_coro
<generator object simple_corotine at 0x0000000000A8A518>
>>> next(my_coro) #先激活生成器,執(zhí)行到y(tǒng)ield val語句 #或者使用send(None)也可以激活生成器 ---->coroutine started >>> my_coro.send(24) #向其中傳入值,x = yield ---->coroutine recvied: 24 Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration #當(dāng)生成器執(zhí)行完畢時會報錯
協(xié)程在運(yùn)行中的四種狀態(tài)
GEN_CREATE:等待開始執(zhí)行
GEN_RUNNING:解釋器正在執(zhí)行,這個狀態(tài)一般看不到
GEN_SUSPENDED:在yield表達(dá)式處暫停
GEN_CLOSED:執(zhí)行結(jié)束
>>> def averager(): ... total = 0.0 ... count = 0 ... aver = None ... while True: ... term = yield aver ... total += term ... count += 1 ... aver = total/count ... >>> coro_avg = averager() >>> coro_avg.send(None) >>> coro_avg.send(10) 10.0 >>> coro_avg.send(20) 15.0 >>> coro_avg.send(30) 20.0 >>> coro_avg.send(40) 25.0
每次循環(huán)結(jié)束在yield出暫停,直至下一個參數(shù)傳進(jìn)來。
3.預(yù)激活協(xié)程的裝飾器(自定義激活的方式)
@裝飾器的作用是什么?裝飾原有的函數(shù),給原油函數(shù)增加一個新的功能和方式。
為什么@可以實(shí)現(xiàn)裝飾器的功能?函數(shù)也是對象,函數(shù)可以作為實(shí)參傳給掐函數(shù)。
>>> def coro_active(func): ... def inner(*args,**kwargs): ... gen = func(*args,**kwargs) ... next(gen) #gen.send(None) ... return gen ... return inner ... >>> @coro_active ... def averager(): ... total = 0.0 ... count = 0 ... aver = None ... while True: ... term = yield aver ... total += term ... count += 1 ... aver = total/count ... >>> coro_avg = averager() >>> coro_avg.send(10) 10.0 >>> coro_avg.send(20) 15.0 >>> coro_avg.send(30) 20.0
4.終止協(xié)程和異常處理
當(dāng)協(xié)程的next函數(shù)或者send函數(shù)發(fā)生錯誤的時候,協(xié)程就會終止掉。
需要創(chuàng)建異常捕捉對協(xié)程的異常情況進(jìn)行處理,關(guān)閉當(dāng)前協(xié)程。
5.讓協(xié)程返回值
yield使用方法 ↩︎
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Python實(shí)現(xiàn)功能完整的個人員管理程序
這篇文章主要介紹了Python實(shí)現(xiàn)功能完整的個人員管理程序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-12-12
TensorFlow卷積神經(jīng)網(wǎng)絡(luò)AlexNet實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了TensorFlow卷積神經(jīng)網(wǎng)絡(luò)AlexNet實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11
解決Django數(shù)據(jù)庫makemigrations有變化但是migrate時未變動問題
今天小編就為大家分享一篇解決Django數(shù)據(jù)庫makemigrations有變化但是migrate時未變動的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
Python之numpy.random.seed()和numpy.random.RandomState()區(qū)別及說明
這篇文章主要介紹了Python之numpy.random.seed()和numpy.random.RandomState()區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2017-10-10
Django學(xué)習(xí)筆記之為Model添加Action
這篇文章主要介紹了Django給admin添加Action,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04
matplotlib.subplot()畫子圖并共享y坐標(biāo)軸的方法
Matplotlib的可以把很多張圖畫到一個顯示界面,本文主要介紹matplotlib.subplot()畫子圖并共享y坐標(biāo)軸的方法,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
python使用py2neo創(chuàng)建neo4j的節(jié)點(diǎn)和關(guān)系
這篇文章主要介紹了python使用py2neo創(chuàng)建neo4j的節(jié)點(diǎn)和關(guān)系,第一步使用py2neo連接neo4j的方法然后根據(jù)dict創(chuàng)建Node,更多相關(guān)資料需要的朋友參考下面文章內(nèi)容2022-02-02
Python基于pygame實(shí)現(xiàn)的font游戲字體(附源碼)
這篇文章主要介紹了Python基于pygame實(shí)現(xiàn)的font游戲字體,涉及Python響應(yīng)鍵盤按鍵動態(tài)操作圖片元素的相關(guān)技巧,需要的朋友可以參考下2015-11-11

