Python:淺談迭代器、生成器與協程的演化路徑

“人生苦短,我用Python”,雖然說大量數學和統計分析庫是一個重要優勢,但是歸根結底,Python的最大優勢就是三點:

但是通常一般來講,當扯到并發的時候,無論是多服務器、多進程、多線程、還是協程,事情都難以避免的開始變得復雜。我們把目光放到并發的最輕量級實現:協程上面,簡單淺談一下關于迭代器。

從迭代器說起

迭代器是訪問集合元素的一種方式,無需知道集合的內部結構。任何實現了__iter____next__方法的對象都是迭代器。迭代器使得你可以逐個遍歷容器內的元素,直到沒有更多元素時拋出StopIteration異常。可以很容易實現一個自定義迭代器,這在自己實現一些需要迭代的數據結構式會有些作用:

class MyIterator:def __init__(self, max):self.current = 0self.max = maxdef __iter__(self):return selfdef __next__(self):if self.current >= self.max:raise StopIterationvalue = self.currentself.current += 1return value# 使用迭代器
for i in MyIterator(5):print(i)

輸出:

0
1
2
3
4

迭代的藝術:生成器

生成器(Generators)是Python中一種特殊的迭代器。與傳統的通過列表、元組等數據結構存儲所有元素不同,生成器僅在需要時生成下一個值,大大節省了內存空間。生成器自動實現了迭代器協議,使得編寫迭代器更為簡單且內存效率更高。

如果想要自行通過迭代器實現與生成器相同功能,也并不困難,如下例子中調用__next__方法與生成器作用類似:

class FibonacciIterator:def __init__(self, max_count):self.max_count = max_countself.current_count = 0self.prev = 0self.curr = 1def __iter__(self):return selfdef __next__(self):if self.current_count >= self.max_count:raise StopIterationelse:self.current_count += 1if self.current_count == 1:return self.prevelif self.current_count == 2:return self.currelse:self.prev, self.curr = self.curr, self.prev + self.currreturn self.curr# 使用自定義迭代器
fib_iter = FibonacciIterator(10)
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())

輸出:

0
1
1
2
3
5
8

生成器最簡單的形式是使用函數定義中的yield語句。每當遇到yield,函數就會暫停并返回一個值給調用者;當再次調用生成器的next()方法時,它會從上次停止的地方繼續執行。上面的迭代器程序略顯復雜,但是使用生成器之后,程序則變得簡單清晰的多。下面的例子使用生成器實現了一樣的功能,這可以很好的幫助理解迭代器的運行順序:


def fibonacci_generator(max_count):prev, curr = 0, 1count = 0while count < max_count:yield prevprev, curr = curr, prev + currcount += 1# 使用生成器
for num in fibonacci_generator(10):print(num)

輸出:

0
1
1
2
3
5
8
13
21
34

Python的協程

在Python中,協程(Coroutines)通常被認為是生成器(Generators)的一個超集。它利用生成器的暫停與恢復機制,實現了非阻塞式的并發執行。協程在生成器的基礎上進行了擴展,增加了更多的控制流特性,如能夠接收輸入、暫停執行等。協程是通過生成器實現的,生成器中的yield關鍵字可以用來實現協程的暫停和恢復執行的功能。Python協程實現,會使用asyncio包,并配合async/await語法糖。

可能只是我個人的YY,似乎Python的協程或多或少的借鑒了JS。從語法到實現方式都非常類似。在現代ES中,async/await語法糖是必不可少,幾乎每個程序都會用到的,而Python也是用相同的關鍵字,從標準化角度,JS先于Python標準化了這兩個語法糖。

一個簡單的Python使用asyncio的例子如下所示:

import asyncioasync def task(name, delay):print(f"{name} start")await asyncio.sleep(delay)print(f"{name} end")async def main():task1 = asyncio.create_task(task("TAsk1", 2))task2 = asyncio.create_task(task("TaSK2", 1))await task1await task2asyncio.run(main()

輸出:

TAsk1 start
TaSK2 start
TaSK2 end
TAsk1 end

上面代碼中,通過asyncio.create_task創建了兩個小任務,任務是異步運行的,并且程序必須等待兩個任務都結束后,main才會返回。注意這里asyncio.create_task創建的task有些類似于JS的:

new Promise().then()

所以兩個task是異步的。如果希望等待Task1完成后再運行Task2,則不需要通過asyncio.create_task創建task,直接再async函數調用前加入await即可,這是JS中一個常用的寫法。如下:

import asyncioasync def main():await task("TAsk1", 2)await task("TaSK2", 1)asyncio.run(main())

輸出:

TAsk1 start
TAsk1 end
TaSK2 start
TaSK2 end

總結

從迭代器,到生成器,最后到協程,理解這個演化路徑,可以更好地理解Python的協程機制。在此之后,加上對asyncio庫的了解,即可熟練掌握Pythong的協程機制了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/35064.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35064.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35064.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# SocketUDP服務器,組播

SocketUDP 自己即是服務器又是客戶端 &#xff0c;在發消息只需要改成對方ip和端口號即可 前提對方必須開啟服務器 socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.107.72"), 8080)); 控件&#xff1a;Button,TextBox,RichTextBox 打開自己服務器 public…

【操作系統】信號處理與阻塞函數|時序競態問題

&#x1f525;博客主頁&#xff1a; 我要成為C領域大神&#x1f3a5;系列專欄&#xff1a;【C核心編程】 【計算機網絡】 【Linux編程】 【操作系統】 ??感謝大家點贊&#x1f44d;收藏?評論?? 本博客致力于知識分享&#xff0c;與更多的人進行學習交流 ? 關于阻塞函數和…

Windows環境部署MySQL_8.4.0 LTS的部署安裝、驗證連接以及卸載全過程實操手冊

前言&#xff1a; 什么是 MySQL MySQL 是一個關系型數據庫管理系統&#xff0c;由瑞典 MySQL AB 公司開發&#xff0c;目前屬于Oracle 公司。MySQL 是一種關系型數據庫管理系統&#xff0c;關系型數據庫將數據保存在不同的表中&#xff0c;而不是將所有數據放在一個大倉庫內&am…

secureCRT中使用python腳本自動化測試vela設備

利用vela設備自帶的wapi命令行&#xff0c;重復執行聯網斷網的命令&#xff0c;測試系統穩定性。 實現如下&#xff0c; # $language "python" # $interface "1.0"# This automatically generated script may need to be # edited in order to work co…

8.12 矢量圖層面要素單一符號使用七(隨機標記填充)

文章目錄 前言隨機標記填充&#xff08;Random Marker Fill&#xff09;QGis設置面符號為隨機標記填充&#xff08;Random Marker Fill&#xff09;二次開發代碼實現隨機標記填充&#xff08;Random Marker Fill&#xff09; 總結 前言 本章介紹矢量圖層線要素單一符號中使用隨…

分班查詢怎么發布?

在現代教育環境中&#xff0c;傳統的學生分班通知方式可能顯得有些過時和低效。通常&#xff0c;這些方式依賴于紙質通知單&#xff0c;這不僅需要大量的物理資源進行打印和分發&#xff0c;而且容易出錯&#xff0c;如丟失、錯誤分發或延遲。 幸運的是&#xff0c;現在有了更高…

掌握Perl并發:線程與進程編程全攻略

掌握Perl并發&#xff1a;線程與進程編程全攻略 引言 Perl作為一種功能強大的編程語言&#xff0c;提供了豐富的并發編程手段。無論是通過threads模塊實現的線程&#xff0c;還是通過fork系統調用產生的進程&#xff0c;Perl都能幫助開發者高效地處理多任務。本文將深入探討如…

解釋Java的垃圾回收機制以及垃圾回收器的工作原理。

Java的垃圾回收機制&#xff08;Garbage Collection&#xff0c;GC&#xff09;是Java虛擬機&#xff08;JVM&#xff09;的一個重要組成部分&#xff0c;它負責自動管理內存&#xff0c;確保內存泄漏和內存溢出錯誤不會發生。垃圾回收器&#xff08;Garbage Collector&#xf…

心靈館咨詢系統小程序心理咨詢平臺聊天咨詢

心靈館咨詢系統小程序&#xff1a;解鎖你的心靈密碼 &#x1f496; 心靈之旅的導航者 在繁忙的現代生活中&#xff0c;我們時常會面臨各種壓力與困惑。心靈館咨詢系統小程序&#xff0c;如同一位貼心的導航者&#xff0c;引領我們探索內心的世界&#xff0c;尋找真正的自我。 …

shell 腳本的部分指令和操作符

終端輸入兩個數&#xff0c;判斷兩數是否相等&#xff0c;如果不相等&#xff0c;判斷大小關系 2.已知網址www.hqyj.com&#xff0c;使用expr截取出www、hqyj、com&#xff0c;不能使用cut&#xff0c;不能出現數字

JavaWeb系列十九: jQuery的DOM操作 上

查找節點, 修改屬性 查找屬性節點: 查找到所需要的元素之后, 可以調用jQuery對象的attr()方法用來 設置/返回 它的各種屬性值 設置屬性值 $(“img”).attr(“width”, “300”);返回屬性值 $(“img”).attr(“width”); 創建節點 創建節點: 使用jQuery的工廠函數$(): $(html標…

硬核實力再亮,玩出夢想科技發布全球首款安卓系統空間計算機

6月25日&#xff0c;玩出夢想科技在新加坡召開全球新品發布會&#xff0c;正式發布全球首款安卓系統空間計算機——玩出夢想MR&#xff0c;填補了空間計算機在安卓生態的空白。 作為品牌沉淀兩年的破曉之作&#xff0c;玩出夢想MR以業內領先軟硬件配置&#xff0c;強大自研算法…

刪除win10未激活水印

通過終止進程來刪除水印 remove.batecho off taskkill /F /IM explorer.exe explorer.exe exit右鍵管理員執行重啟

解決了!暗影精靈8 Pro酷睿版無聲音,揚聲器和麥克風都沒有聲音!

困擾好幾天的問題解決了&#xff01; 暗影精靈8 Pro酷睿版無聲音&#xff0c;揚聲器和麥克風都沒有聲音&#xff01;&#xff01;方法適用于OMEN by HP Gaming Laptop 16-k0xxx&#xff08;暗影精靈8 Pro酷睿版&#xff09;的Windows 10聲卡驅動&#xff01; 朋友們&#xff…

【應用開發一】LED開發

文章目錄 1應用層控制外設的兩種方式2 sysfs和/sys關系3 LED控制方式3.1 基本情況3.2 LED屬性文件介紹3.3 命令行屬性測試3.4 led程序3.5 開發板上測試 1應用層控制外設的兩種方式 使用設備文件控制 在Linux系統下&#xff0c;一切皆是文件。應用層控制底層硬件同樣也是通過文…

如何在 Linux 上安裝 Docker Desktop

如何在 Linux 上安裝 Docker Desktop Docker 是一個用于開發、部署和運行應用程序的開放平臺。Docker Desktop 是 Docker 在 macOS 和 Windows 上的官方客戶端&#xff0c;現在也支持 Linux 系統。本文將詳細介紹如何在 Linux 上安裝 Docker Desktop。 系統要求 在開始安裝之…

第100+12步 ChatGPT學習:R實現KNN分類

基于R 4.2.2版本演示 一、寫在前面 有不少大佬問做機器學習分類能不能用R語言&#xff0c;不想學Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi轉一下就得了唄。 加上最近也沒啥內容寫了&#xff0c;就幫各位搬運一下吧。 二、R代碼實現KNN分類 &#xff08;1&a…

【Docker】Consul 和API

目錄 一、Consul 1. 拉取鏡像 2. 啟動第一個consul服務&#xff1a;consul1 3. 查看consul service1 的ip地址 4. 啟動第二個consul服務&#xff1a;consul2&#xff0c; 并加入consul1&#xff08;使用join命令&#xff09; 5. 啟動第三個consul服務&#xff1a;consul3&…

攻擊者開始使用 XLL 文件進行攻擊

近期&#xff0c;研究人員發現使用惡意 Microsoft Excel 加載項&#xff08;XLL&#xff09;文件發起攻擊的行動有所增加&#xff0c;這項技術的 MITRE ATT&CK 技術項編號為 T1137.006。 這些加載項都是為了使用戶能夠利用高性能函數&#xff0c;為 Excel 工作表提供 API …