人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

python實(shí)習(xí)總結(jié)(yeild,async,azwait和協(xié)程)

發(fā)布日期:2021-12-28 05:23 | 文章來(lái)源:腳本之家

一、yield使用簡(jiǎn)析

yield是一個(gè)生成器generator,返回一個(gè)interable對(duì)象。

該對(duì)象具有next()方法,可以通過(guò)next()查看接下來(lái)的元素是什么。

1.interable對(duì)象 ,可以遍歷的對(duì)象,如: list,str,tuple,dict,file,xrange等。

2.yield的作用是什么?只是循環(huán)里面的獲取中間變量的一個(gè)方法,把想要的變量每次使用yield保存起來(lái)直至循環(huán)結(jié)束,循環(huán)結(jié)束得到了一個(gè)generator對(duì)象

3.為什么使用yield?使用yield,一個(gè)函數(shù)改寫成generator,便具有了迭代的能力,比起用類的實(shí)例保存狀態(tài)計(jì)算下一個(gè)需要迭代的值,代碼更加簡(jiǎn)潔,執(zhí)行流程十分簡(jiǎn)單。

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 是無(wú)法迭代的,而 fab(5) 是可迭代的。

>>>from collections import Iterable 
>>> isinstance(fab, Iterable) 
False 
>>> isinstance(fab(5), Iterable) 
True

5.yield在文件讀取的應(yīng)用?

如果字節(jié)使用read()讀取一個(gè)文件,會(huì)導(dǎo)致不可預(yù)測(cè)的內(nèi)存占用。好的方法是使用yield,固定長(zhǎng)度的緩沖區(qū)來(lái)不斷讀取文件,生成讀文件的迭代的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é)程是什么?

一種用戶級(jí)輕量級(jí)的線程,擁有自己的寄存器上下文和棧。

協(xié)程切換時(shí)候,將寄存器和棧保存在其他地方,當(dāng)返回的時(shí)候,恢復(fù)原先保存的寄存器上下文和棧。

  • 為什么使用協(xié)程?

主流語(yǔ)言采用多線程并發(fā),線程相關(guān)的概念是搶占式多任務(wù),協(xié)程相關(guān)的協(xié)作式多任務(wù)。

不管是多進(jìn)程還是多線程,每次阻塞、切換陷入系統(tǒng)調(diào)用。

CPU跑操作系統(tǒng)的調(diào)度程序,調(diào)度程序決定運(yùn)行哪一個(gè)進(jìn)程(線程)。

線程非常小心的處理同步問(wèn)題,而協(xié)程完全不存在這個(gè)問(wèn)題。

對(duì)于CPU而言,多協(xié)程是單線程,CPU不會(huì)考慮調(diào)度、切換上下文,省去CPU的切換開(kāi)銷。協(xié)程好于多線程的原因。

  • 如何使用協(xié)程?

多進(jìn)程+協(xié)程下,避開(kāi)了CPU切換的開(kāi)銷,又能把多個(gè)CPU充分利用起來(lái),這種方式對(duì)于數(shù)據(jù)量較大的爬蟲還有文件讀寫之類的效率提升是巨大的。

2.如何處理200W數(shù)量的url,把所有的url保存下來(lái)?

  • 單進(jìn)程+單線程
  • 單進(jìn)程+多線程:開(kāi)十個(gè)線程,速度不能提高十倍。線程的切換是有開(kāi)銷的,無(wú)能無(wú)限的創(chuàng)建線程。
  • 多進(jìn)程+多線程:多進(jìn)程的每個(gè)進(jìn)程占用一個(gè)CPU,多線程一定程度上繞過(guò)了阻塞時(shí)間,所以相比單進(jìn)程的多線程效率更高。
  • 協(xié)程

3.使用async的await和gather

  • await接受一個(gè)協(xié)程列表,返回done、pending兩個(gè)列表。done是已經(jīng)完成的協(xié)程,pending是仍在跑的協(xié)程。通過(guò).result()獲取完成的結(jié)果
  • gather以gather(cro1, cro2, cro3, cro4…)的方式接受協(xié)程,返回的是一個(gè)結(jié)合了這么多個(gè)任務(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é)程的過(guò)程

協(xié)程中yield是控制流程的方式。

yield同接收器一樣,是一個(gè)生成器,需要先激活才能使用。

>>> 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語(yǔ)句  #或者使用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í)行完畢時(shí)會(huì)報(bào)錯(cuò)

協(xié)程在運(yùn)行中的四種狀態(tài)

GEN_CREATE:等待開(kāi)始執(zhí)行

GEN_RUNNING:解釋器正在執(zhí)行,這個(gè)狀態(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出暫停,直至下一個(gè)參數(shù)傳進(jìn)來(lái)。

3.預(yù)激活協(xié)程的裝飾器(自定義激活的方式)

@裝飾器的作用是什么?裝飾原有的函數(shù),給原油函數(shù)增加一個(gè)新的功能和方式。

為什么@可以實(shí)現(xiàn)裝飾器的功能?函數(shù)也是對(duì)象,函數(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ā)生錯(cuò)誤的時(shí)候,協(xié)程就會(huì)終止掉。

需要?jiǎng)?chuàng)建異常捕捉對(duì)協(xié)程的異常情況進(jìn)行處理,關(guān)閉當(dāng)前協(xié)程。

5.讓協(xié)程返回值

yield使用方法 ↩︎

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注本站的更多內(nèi)容!

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開(kāi)通

自選配置、實(shí)時(shí)開(kāi)通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問(wèn)服務(wù)

1對(duì)1客戶咨詢顧問(wèn)

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部