pytest之fixture中yield詳解

1. fixture——yield介紹

fixture的teardown操作并不是獨立的函數,用yield關鍵字呼喚teardown操作。前面通過fixture實現了在每個用例之前執行初始化操作,那么用例執行完之后,如需要清除數據(或還原)操作,可以使用yield來實現。

yield是一個關鍵字,它不是單獨存在的,要寫在fixture標記的固件中。我們在聲明的固件fixture中加入yield關鍵字,在它下面寫測試用例執行后想要運行的代碼;其他有關于固件的使用沒有任何差別。需要說明的一點是我們在pytest主函數中增加一個參數-setup-show,它會顯示出固件的執行情況。

自動執行清理邏輯:無論測試是否通過、是否拋出異常,yield后的代碼始終會被執行。這確保資源(如文件、網絡連接)被正確釋放。但是如果固件中的yield之前的代碼也是相當于setup部分的代碼,出現錯誤或斷言失敗,那么yield后的代碼將不會再執行,當然測試用例中的代碼也不會執行。

2. 基本原理:通過 yield 分割執行階段

在 fixture 函數中,yield語句將代碼分為兩部分:

  • 前置操作yield之前的代碼在測試執行前運行(類似于 setup)。
  • 返回值yield后的值作為 fixture 的返回值傳遞給測試函數。
  • 后置操作yield之后的代碼在測試執行后運行(類似于 teardown),無論測試是否通過。

用法示例

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : test_yield.py
@Time    : 2023/8/23 0:50
@desc   : fixture裝飾的函數里,yield的代碼,是pytest用例執行完后再執行的
'''
import pytest@pytest.fixture
def fix1():print('\nfix1,用例前置')yieldprint('\nfix1,用例執行完成,收尾')# 測試用例
def test_yield(fix1):print('fixture + yield的測試用例')if __name__ == '__main__':pytest.main(['-s', 'test_yield.py'])

控制臺:
在這里插入圖片描述

3. 處理異常的清理

yield前的代碼拋出異常,yield后的清理代碼不會執行。需使用try/finally包裹:

@pytest.fixture
def safe_setup():resource = Nonetry:resource = acquire_resource()  # 可能拋出異常yield resourcefinally:if resource:resource.release()  # 確保資源被釋放

4. yield詳解

在 Python 中,yield是創建生成器(Generator)的核心關鍵字。生成器是一種特殊的迭代器,它允許你在迭代過程中動態生成值,而不是一次性生成所有值。這種特性讓生成器在處理大數據、優化內存和實現異步編程時非常有用。

yield: return 
yield: return + generator 的一部分
PS:帶yield的函數才是完整的generator 

(1) 生成器的本質:按需生成的迭代器

生成器是 Python 中實現惰性計算的主要方式,它有兩種形式:

a. 生成器函數(Generator Function)
使用yield關鍵字的函數,調用時返回一個生成器對象:

def count_up_to(n):i = 0while i <= n:yield i  # 暫停執行并返回當前值i += 1# 創建生成器對象(不會立即執行函數體)
gen = count_up_to(3)# 通過迭代獲取值
print(next(gen))  # 輸出: 0
print(next(gen))  # 輸出: 1
print(next(gen))  # 輸出: 2
print(next(gen))  # 輸出: 3
print(next(gen))  # 拋出 StopIteration 異常

b. 生成器表達式(Generator Expression)
類似列表推導式,但使用圓括號:

gen = (x**2 for x in range(3))  # 創建生成器print(next(gen))  # 輸出: 0
print(next(gen))  # 輸出: 1
print(next(gen))  # 輸出: 4

(2) yield 的核心作用:暫停與恢復執行

當生成器函數被調用時,函數體不會立即執行,而是返回一個生成器對象。每次調用next()時:

  • 生成器從上次暫停的位置繼續執行(或從函數起始處開始)。
  • 執行到yield語句時,生成一個值并暫停執行。
  • 下一次調用next()時,繼續執行yield之后的代碼。

總結:yield和return的關系和區別

yield的函數是一個生成器,而不是一個函數了。這個生成器有一個函數就是next函數,next就相當于“下一步”生成哪個數,這一次的next開始的地方是接著上一次的next停止的地方執行的。所以調用next的時候,生成器并不會從yield_demo函數的開始執行,而是接著上一步開始,然后遇到yield后,return出要生成的數,此步就結束。

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : yield.py
@Time    : 2023/8/23 17:28
@desc   : yield詳解
1.程序開始執行以后,因為yield_demo函數終有yield關鍵字,
所以test函數并不會真正的執行,而是先得到一個生成器y
2.直到調用next方法,yield_demo函數正式開始執行,先執行yield_demo函數中的print方法,然后進入while循環
3.程序遇到yield關鍵字,然后把yield想成是return,return了一個8之后,程序停止,
并沒有執行賦值給a操作,此時next(y)語句執行完成,所以輸出前面兩行(第一行是while上面的print的結果,第二行是return出來的結果)
4.程序執行print("**********************")
5.又開始執行下面的print(next(y)),這個時候是從剛才next程序停止的地方開始執行,
也就是要執行a的賦值操作,這個時候因為賦值操作的右邊是沒有值的,已經被return出去了
這個時候a的值是none,所以接下來的輸出是a:none
6.程序會繼續在whili里執行,又一次碰到yield,這個時候同樣return出8,然后程序停止。
print函數輸出的8就是這次return出的8
'''def yield_demo():print('begin================')while True:a = yield 8print('a', a)y = yield_demo() # 這句不會打印出東西,因為test函數終有yield關鍵字,所以yield_demo函數并不會真正的執行,而是先得到一個生成器y
print(next(y))
print('*******************************')
print(next(y))
print('*******************************')

控制器:
在這里插入圖片描述

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

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

相關文章

Nginx 動靜分離原理與工作機制詳解:從架構優化到性能提升

前言&#xff1a;在 Web 應用架構不斷演進的今天&#xff0c;如何高效處理日益增長的訪問量和復雜的業務邏輯&#xff0c;成為開發者必須面對的挑戰。當我們在瀏覽器中打開一個網頁&#xff0c;那些直觀可見的 HTML 頁面、精美絕倫的圖片、流暢運行的 JavaScript 腳本&#xff…

介紹electron

一、Electron 是什么&#xff1f; Electron 是一個基于 Chromium 和 Node.js 的框架&#xff0c;允許開發者使用前端技術&#xff08;HTML/CSS/JavaScript&#xff09;構建原生桌面應用。其核心優勢在于&#xff1a; 跨平臺&#xff1a;一次開發&#xff0c;生成 Windows、ma…

DeepSeek與詭秘之主

1、大模型像個腐儒 其實從大模型的訓練方式來看&#xff0c;它算不上天賦異稟。尤其在成長階段&#xff0c;大模型那種種令人驚艷的表現&#xff0c;足夠讓人誤以為這是個天才。 可人這種生物&#xff0c;注定是貪婪的。在大模型成長后期&#xff0c;伴隨著各種技巧的驗證&…

動手實踐OpenHands系列學習筆記5:代理系統架構概述

筆記5&#xff1a;代理系統架構概述 一、引言 AI代理系統是一種能夠自主執行任務的智能軟件架構&#xff0c;OpenHands作為AI驅動的軟件開發代理平臺&#xff0c;擁有完整的代理系統架構設計。本筆記將探討AI代理架構的基本原理&#xff0c;并通過分析OpenHands核心架構&…

智能電動汽車 --- 車輛網關路由緩存

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

Spring中實現依賴注入(DI)的三種方式

1. Autowired 字段注入&#xff08;不推薦&#xff09;? Service public class UserService {Autowired // 直接在字段上注入private UserRepository userRepository; } ??原理??&#xff1a;Spring 啟動時掃描所有 Component、Service 等注解的類&#xff0c;發現 Aut…

Alpha系統聯結大數據、GPT兩大功能,助力律所管理降本增效

如何通過AI工具實現法律服務的提質增效,是每一位法律人都積極關注和學習的課題。但從AI技術火爆一下,法律人一直缺乏系統、實用的學習資料,來掌握在法律場景下AI的使用技巧。 今年5月,iCourt攜手貴陽律協大數據與人工智能專業委員會,聯合舉辦了《人工智能助力律師行業高質量發…

UI前端與數字孿生融合新趨勢:智慧家居的智能化控制與個性化服務

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;數字孿生重構智慧家居的技術范式在智能家居滲透率快速提升的今天&#xf…

R語言初學者爬蟲簡單模板

習慣使用python做爬蟲的&#xff0c;反過來使用R語言可能有點不太習慣&#xff0c;正常來說R語言好不好學完全取決于你的學習背景以及任務復雜情況。對于入門學者來說&#xff0c;R語言使用rvesthttr組合&#xff0c;幾行代碼就能完成簡單爬取&#xff08;比Python的Scrapy簡單…

如何決定idea項目中使用的是哪個版本的jdk?是idea中配置決定的?還是maven中配置決定的

? IDEA 項目中使用哪個 JDK&#xff0c;是由以下幾部分共同決定的&#xff1a; 階段決定因素舉例項目編譯&#xff08;編譯器&#xff09;IDEA 設置的 Project SDK 和模塊 SDKProject Structure → Project / Modules 中配置的 JDKMaven 構建Maven 使用的 JDK&#xff08;即 …

Docker拉取bladex 、 sentinel-dashboard

docker pull bladex/sentinel-dashboard 是用于從 Docker Hub 拉取 Alibaba Cloud Sentinel Dashboard 鏡像的命令&#xff0c;默認會拉取最新版本。以下是詳細的操作步驟及注意事項&#xff1a; 操作步驟 1. 拉取鏡像 &#xff1a;在終端輸入 docker pull bladex/sentinel-…

從零開始理解 JavaScript 中的 `window.parent`、`top` 和 `self`

從零開始理解 JavaScript 中的 window.parent、top 和 self 在 JavaScript 開發中&#xff0c;window 對象是瀏覽器環境中最重要的全局對象之一。它不僅代表了瀏覽器窗口本身&#xff0c;還提供了對窗口層級關系的訪問能力。對于處理嵌套框架&#xff08;iframe&#xff09;或…

vue3引入海康監控視頻組件并實現非分屏需求一個頁面同時預覽多個監控視頻;

海康監控視頻非分屏需求&#xff0c;一個頁面引用多個視頻組件; js文件位置index.html 引入js文件//根據自己路徑引入哈<script src"static/haiKangWeb3.0/jquery-1.7.1.min.js"></script><script type"text/javascript" id"videonode…

Policy Gradient【強化學習的數學原理】

目錄 policy 與表格方式的區別&#xff1a; metric to define optimal policies 1. weighted averge 2. the average reward 問題&#xff1a; 梯度計算 如何理解policy-gradient&#xff1f; policy gradient與表格方式(value based)的區別&#xff1a; policy 通過參…

【深圳大學機器學習】實驗一:PCA算法

實驗目的 1、實現PCA算法的人臉重構&#xff0c;即用20,40,60,80,...,160個投影來重構圖像的效果。 2、實現PCA算法的人臉識別&#xff0c;給出不少于三個人臉數據庫上 10,20,30,...,160維的人臉識別識別率&#xff0c;并打印出識別率變化曲線圖。 3、用PCA用來進行人臉圖像…

編程中的英語

case this are mixed case version case在這里表示大小寫&#xff1f;為什么case可以表示大小寫的含義&#xff1f; “case”在這里的含義 在句子“This are mixed case version”中&#xff0c;“case”確實表示“大小寫”&#xff0c;用于描述字母的形式&#xff08;大寫字母…

LabVIEW開發關節軸承試驗機

LabVIEW通過NI硬件&#xff08;CompactRIO 實時控制器、FPGA 模塊等&#xff09;與模塊化軟件設計的結合&#xff0c;實現試驗參數采集、多工況控制、數據存儲的并行處理&#xff0c;體現LabVIEW 在工業自動化中對多任務并發場景的高效支持能力。 ? 應用場景 關節軸承試驗機…

【Linux庖丁解牛】— 動靜態庫的制作和使用!

1. 什么是庫庫是寫好的現有的&#xff0c;成熟的&#xff0c;可以復?的代碼。現實中每個程序都要依賴很多基礎的底層庫&#xff0c;不可能 每個?的代碼都從零開始&#xff0c;因此庫的存在意義?同尋常。 本質上來說庫是?種可執?代碼的?進制形式&#xff0c;可以被操作系統…

Hadoop集群啟動 (ZooKeeper、HDFS、YARN、Hbase)

一、啟動ZooKeeper集群 sh /opt/modules/zookeeper-3.4.14/bin/zkServer.sh start[hadoopcentos01 ~]$ sh /opt/modules/zookeeper-3.4.14/bin/zkServer.sh start ZooKeeper JMX enabled by default Using config: /opt/modules/zookeeper-3.4.14/bin/../conf/zoo.cfg Startin…

React Hooks全面解析:從基礎到高級的實用指南

React Hooks全面解析&#xff1a;從基礎到高級的實用指南 React Hooks自2018年16.8版本引入以來&#xff0c;徹底改變了React組件的開發方式。** Hooks使函數組件獲得了與類組件同等的表達能力&#xff0c;同時簡化了代碼結構&#xff0c;提升了可維護性**。本文將系統介紹Rea…