91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

生成器Generator的原理及用法

發布時間:2021-07-06 09:46:59 來源:億速云 閱讀:310 作者:chen 欄目:web開發

本篇內容主要講解“生成器Generator的原理及用法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“生成器Generator的原理及用法”吧!

基本用法

我們知道,函數體包含 yield 關鍵字的函數不是一個普通函數。這種函數叫做 生成器 ( generator  ),一般用于循環處理結構,應用得當可以極大優化內存使用效率。例如,設計一個函數,打開文件并將每一行轉成大寫并返回:

def read_file_upper(path):     lines = []     with open(path) as f:         for line in f:             lines.append(line.upper())     return lines

這個版本的函數,在內部創建了一個 list 對象,用于保存轉換結果。for  循環則遍歷文件每一行,將其轉成大寫并追加到列表中。這樣一來,文件中的每一行均需要保存在列表中,如果文件很大,內存開銷可想而知。

我們可以借助 yield 關鍵字,將 read_file_upper 函數改成生成器版本。函數主體邏輯沒有任何變化,只是將每行數據的處理結果通過  yield 逐個返回,而不是收集到 list 對象后再返還。

def iter_file_upper(path):     with open(path) as f:         for line in f:             yield line.upper()

如果現在有一個文本文件 data.txt ,里面包含以下內容:

hello, world life is short, use python my wechat id is: coding-fan bye

用 iter_file_upper 生成器,我們可以這樣對它進行處理:

>>> for line in iter_file_upper('text.txt'): ...     print(line.strip()) HELLO, WORLD LIFE IS SHORT, USE PYTHON MY WECHAT ID IS: CODING-FAN BYE

iter_file_upper 生成器用法與 read_file_upper  函數大致相同,但它不會一次性拿住文件所有數據行,而是逐行處理、逐個返回,這樣便將內存使用量降到最低。

行為觀察

那么,生成器為什么會有這樣的奇效呢?我們接著觀察:

>>> g = iter_file_upper('text.txt') >>> g <generator object iter_file_upper at 0x103becd68>

我們調用 iter_file_upper 后,得到一個生成器對象,而不是文件處理結果,這時 iter_file_upper 還未開始執行。

當我們調用 next 函數從生成器接收下一個數據時,iter_file_upper 開始執行并在 yield  處停下來,并把第一行的處理結果返回給我們:

>>> next(g) 'HELLO, WORLD\n'

這時,生成器處于暫停狀態,沒有我們的指令,它不會接著處理第二行數據。

當我們再次執行 next 函數時,生成器再次恢復執行,處理下一行數據并在 yield 處再次暫停:

>>> next(g) 'LIFE IS SHORT, USE PYTHON\n'

生成器記住了自己的執行進度,每次調用 next 函數,它總是處理并生產下一個數據,完全不用我們瞎操心:

>>> next(g) 'MY WECHAT ID IS: CODING-FAN\n' >>> next(g) 'BYE\n'

當 iter_file_upper 代碼邏輯執行完畢,它將給 next 拋一個異常,以此通知調用者它已經結束了:

>>> next(g) Traceback (most recent call last):   File "<stdin>", line 1, in <module> StopIteration

因此,我們可以簡單認為 for-in 循環在 Python 虛擬機內部是這樣實現的:

  • 不斷調用 next 函數讓生成器產出數據;

  • 直到生成器拋出 StopIteration 異常;

在經典的線程模型中,每個線程有一個獨立的執行流,只能執行一個任務。如果一個程序需要同時處理多個任務,可以借助 多進程 或者 多線程  技術。假設一個站點需要同時服務多個客戶端連接,可以為每個連接創建一個獨立的線程進行處理。

不管線程還是進程,切換時都會帶來巨大的開銷:用戶態/內核態切換、執行上下文保存和恢復、CPU緩存刷新等等。因此,用線程或進程來驅動小任務的執行,顯然不是一個理想的選擇。

那么,除了線程和進程,還有其他解決方案嗎?

到此,相信大家對“生成器Generator的原理及用法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临清市| 明星| 潍坊市| 新龙县| 湛江市| 天全县| 龙山县| 昆山市| 桐梓县| 抚远县| 凭祥市| 措美县| 安达市| 罗甸县| 沁水县| 上犹县| 许昌市| 忻城县| 云浮市| 澄迈县| 富平县| 宽甸| 贡山| 西乌珠穆沁旗| 长宁县| 南木林县| 若尔盖县| 阿拉尔市| 永善县| 德格县| 铜山县| 宾川县| 花垣县| 元朗区| 南雄市| 东台市| 隆子县| 尚志市| 梧州市| 清涧县| 忻州市|