首頁 >後端開發 >Python教學 >Python協程的實作方法有哪些?

Python協程的實作方法有哪些?

WBOY
WBOY轉載
2023-04-23 10:22:061778瀏覽

1.協程

協程不是電腦提供的,電腦只提供:行程、執行緒。協程時人工創造的一種使用者態切換的微進程,使用一個執行緒去來回切換多個進程

實現協程的幾種方法

  • greenlet :早期模組

  • yield關鍵字:可以儲存程式碼,儲存狀態

  • asyncio裝飾器(3.4)

  • #async、await關鍵字(3.5)【建議】

1.1greenlet實作協程

pip install greenlet

from greenlet import greenlet
def fun1():
  gre2.switch()#切换到fun2
  pass
def fun2():
  gre1.switch()#切换到fun1
  pass
gre1 = greenlet(func1)
gre2 = greenlet(func2)
gre1.switch()#先去执行fun1

1.2yield關鍵字實作協程

def func1():
    yield 1
    yield from func2()
    yield 2
    
def func2():
    yield 3
    yield 4
f1 = func1()
for item in f1:
    print(item,end=" ")
    
#打印结果
1 3 4 2

1.3使用asyncio模組實現協程

再python3.4版本之後才可以用(不用安裝,在標準庫中)

import asyncio
#使用该装饰器装饰后,该函数就是一个协程函数
@asyncio.coroutine
def func1():
    print(1)
    #遇到IO操作时,会自动切换到taks中的其他任务函数
    yield from asyncio.sleep(2)
    print(2)

@asyncio.coroutine
def func2():
    print(3)
    yield from asyncio.sleep(2)
    print(4)
    
#将两个协程函数封装成一个tasks列表
tasks = [
    asyncio.ensure_future(func1()),
    asyncio.ensure_future(func2())
]
#
loop = asyncio.get_event_loop()
loop.run_until_complete(func1())

1.4async & await關鍵字實現協程

import asyncio
#使用该装饰器装饰后,该函数就是一个协程函数

async def func1():
    print(1)
    #遇到IO操作时,会自动切换到tasks中的其他任务函数
    await asyncio.sleep(2)
    print(2)


async def func2():
    print(3)
    await asyncio.sleep(2)
    print(4)
    
#将两个协程函数封装成一个tasks列表
tasks = [
    asyncio.ensure_future(func1()),
    asyncio.ensure_future(func2())
]

loop = asyncio.get_event_loop()
loop.run_until_complete(tasks)

2.協程意義

在執行緒中如果遇到IO等待時間,執行緒不會傻等著,會利用空閒的時間去做其他事情,也就是進程異步執行。

#协程请求资源使用第三方库aiohttp
import aiohttp

3.非同步程式設計

3.1時間循環

明白成一個死循環,去偵測並執行某些程式碼

#伪代码
任务列表 = [task1,task2...]
while True:
  for 就绪任务 in 可执行任务列表:
    执行
  for 已完成任务 in 已完成任务列表:
    从任务列表中删除

import asyncio 

#生成一个书简循环
loop = asyncio.get_event_loop()
#将任务放到任务列表中
loop.run_until_complete(任务)

3.2案例

協程函數,

定義函數的時候,用async def 函數名稱

協程物件:執行協程函數的時候得到一個協程物件

async def func():
  pass
result = func()

注意:執行協程函數時得到的協程對象,函數內部程式碼不會執行

import asyncio
async def func():
  print("哈喽")

f = func()#协程对象

loop = asyncio.get_event_loop()#创建循环对象
loop.run_until_complete(f)#通过循环对象执行协程对象

#python3.7可以直接
asyncio.run(f)

3.3await關鍵字

await 可等待的物件{協程對象,Future對象,Task物件} (類似I O 等待)

import asyncio
async def func():
  print("哈喽")
  re = await asyncio.sleep(2)
	print(re)
asyncio.run(func())

await就是等待物件的值得到結果後再繼續向下執行

import asyncio
async def other():
  print("start")
  await asyncio.sleep(2)
  print("end")
  return 1

async def fun():
  print("执行协程函数内部代码")
  #遇到IO操作时会挂起当前协程任务,等IO操作完成后再继续往下执行,当前协程挂起时,时间循环对象可以执行其他协程任务
  re = await other()
  print("IO请求结束,结果为:",re)
  
asyncio.run(func())

執行結果 

#執行協程函數內部程式碼
start
end
IO請求結束,結果為: 1

以上是Python協程的實作方法有哪些?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除