<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
import pluggy # HookspecMarker 和 HookimplMarker 實質上是一個裝飾器帶引數的裝飾器類,作用是給函數增加額外的屬性設定 hookspec = pluggy.HookspecMarker("myproject") hookimpl = pluggy.HookimplMarker("myproject") ''' HookspeckMarker: 傳入firstresult=True時,獲取第一個plugin執行結果後就停止繼續執行 @hookspec(firstresult=True) historic - 表示這個 hook 是需要儲存call history 的,當有新的 plugin 註冊的時候,需要回放歷史 hookimpl: 當傳入tryfirst=True時,表示這個類的hook函數會優先執行,其他的仍然按照後進先出的順序執行 當傳入trylast=True,表示當前外掛的hook函數會盡可能晚的執行,其他的仍然按照後進先出的順序執行 當傳入hookwrapper=True時,需要在這個plugin中實現一個yield,plugin先執行yield之前的程式碼, 然後去執行其他的pluggin,然後再回來執行yield之後的程式碼,同時通過yield可以獲取到其他外掛執行的結果 ''' # 定義自己的Spec,這裡可以理解為定義介面類 class MySpec: # hookspec 是一個裝飾類中的方法的裝飾器,為此方法增額外的屬性設定,這裡myhook可以理解為定義了一個介面 # 會給當前方法新增屬性 鍵為 {self.project_name + "_spec"} 值是裝飾器傳入的引數 @hookspec def myhook(self, arg1, arg2): pass # 定義了一個外掛 class Plugin_1: # 外掛中實現了上面定義的介面,同樣這個實現介面的方法用 hookimpl裝飾器裝飾,功能是返回兩個引數的和 @hookimpl def myhook(self, arg1, arg2): print("inside Plugin_1.myhook()") return arg1 + arg2 # 定義第二個外掛 class Plugin_2: # 外掛中實現了上面定義的介面,同樣這個實現介面的方法用 hookimpl裝飾器裝飾,功能是返回兩個引數的差 @hookimpl(hookwrapper=True) def myhook(self, arg1, arg2): out = yield print("inside Plugin_2.myhook()") return arg1 - arg2 # 範例化一個外掛管理的物件,注意這裡的名稱要與檔案開頭定義裝飾器的時候的名稱一致 pm = pluggy.PluginManager("myproject") # 將自定義的介面類加到勾點定義中去 pm.add_hookspecs(MySpec) # 註冊定義的兩個外掛 pm.register(Plugin_1()) pm.register(Plugin_2()) # 通過外掛管理物件的勾點呼叫方法,這時候兩個外掛中的這個方法都會執行,而且遵循後註冊先執行即LIFO的原則,兩個外掛的結果講義列表的形式返回 results = pm.hook.myhook(arg1=1, arg2=2) print(results)
註冊外掛 (register): 傳遞實現外掛的實體類物件
判斷是否傳遞外掛名字,如果沒傳,就獲取物件的name屬性,如果還沒有就直接用 id() 生產一個隨機字串做當前物件在外掛中的名字
判斷名字是否存在,或者是否已被註冊: self._name2plugin 和 self._plugin2hookcaller,前者是用 plugin_name 做 key,後者是用 plugin object 做 key,判斷是否已經註冊過重複的 plugin
self._name2plugin[plugin_name(外掛名字)] = plugin(傳遞的實體類物件)
self._plugin2hookcallers[plugin(傳遞的實體類物件)] = hookcallers = [],其實就是初始化一下 self._plugin2hookcallers[plugin],因為列表的參照傳遞,所有直接修改 hookcallers 也可以作用在 self 中
遍歷實體類物件的方法列表,判斷是否被 impl 裝飾:
先判斷參數列是否為空: 如果不為空,進行設定預設值 (其實正常是不會出現沒有值的情況),然後從實體類物件中獲取到該方法的物件
判斷 self.hook 中是否以及註冊了當前外掛 (就是 add_hookspecs 註冊的 spec 中是否有當前方法)
hook.has_spec() 判斷註冊 spec 的 spec 屬性不為空
hook._maybe_apply_history(hookimpl)
a.判斷是否有_call_history 這個屬性
hook._add_hookimpl(hookimpl):
a.判斷是否為 hookwrapper 為 True,新增到不同的 wrappers 中
b.判斷是否有 trylast tryfirst 屬性,將 hookimpl 存放到對應位置
c.將 hook 新增到 hookcallers 中
遍歷結束後,返回 plugin_name(第一步產生)
執行外掛 pm.hook.myhook(arg1=1, arg2=2):本質就是呼叫物件的call方法
self._inner_hookexec(hook(hook 物件), methods(外掛), kwargs(引數))
# 實際呼叫,也就是hook.multicall的方法 self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( methods, kwargs, firstresult=hook.spec.opts.get("firstresult") if hook.spec else False, )
1. 先將 hook_impls 變成一個可迭代物件 (reversed(hook_impls))
2. 先把順序引數的參數列,拿到 (列表推導式)
3. 判斷需不需要將其他外掛執行的結果傳遞進去
- 需要
- 先從 hook_impl 中拿出對應的方法並且傳遞引數,執行關鍵字 yield 前面部分
- 然後 next()
- 最後將這個方法新增到 teardowns 列表中去- 不需要
- 先從 hook_impl 中拿出對於的方法並且傳遞引數
- 判斷執行後的返回值是不是為空,不為空則新增到 results 列表中
- 最後判斷是否有 firstresult 屬性,如果有直接結束迴圈
4. 最後執行 (finally 中程式碼)
- 如果 firstresult 為 true,那麼直接返回第一個外掛返回的結果即可
- 執行 teardowns 列表中的需要最後執行的外掛
- 通過迭代器的 send 方法,將上幾個外掛的結果傳遞進去
5. 返回 result 物件 :會判斷是否有報錯 如果沒有直接返回結果列表,如果有報錯會丟擲異常
以上就是Python測試框架pytest核心庫pluggy詳解的詳細內容,更多關於Python pytest庫pluggy的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45