[英]Decorator with parameters
你能解釋一下以下裝飾器是如何工作的:
def set_ev_cls(ev_cls, dispatchers=None):
def _set_ev_cls_dec(handler):
if 'callers' not in dir(handler):
handler.callers = {}
for e in _listify(ev_cls):
handler.callers[e] = _Caller(_listify(dispatchers), e.__module__)
return handler
return _set_ev_cls_dec
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def _switch_features_handler(self, ev):
datapath = ev.msg.datapath
....
請不要詳細了解該功能內部的內容。 我對帶有參數的裝飾器在這里包裝方法感興趣。 順便說一下,這是Ryu(事件注冊機制)的代碼段。
先感謝您
首先,裝飾器只是一個用函數調用的函數。 特別是,以下是(幾乎)相同的事情:
@spam
def eggs(arg): pass
def eggs(arg): pass
eggs = spam(eggs)
那么,當裝飾器獲取參數時會發生什么? 一樣:
@spam(arg2)
def eggs(arg): pass
def eggs(arg): pass
eggs = spam(arg2)(eggs)
現在,請注意函數_set_ev_cls_dec
(最終返回並用於代替_switch_features_handler
)是一個局部函數,在裝飾器內定義。 這意味着它可以封閉外部函數的變量,包括外部函數的參數。 因此,它可以在調用時使用handler
參數,以及它在裝飾時獲得的ev_cls
和dispatchers
參數。
所以:
set_ev_cls_dev
創建一個本地函數,並在其ev_cls
和dispatchers
參數周圍返回一個閉包,並返回該函數。 _switch_features_handler
作為它的參數,它會修改和添加一個返回參數callers
屬性,它是一個字典_Caller
從封閉在建對象dispatchers
參數和鍵控關閉該封閉了ev_cls
參數。 在不詳細說明內部發生什么的情況下解釋其工作原理? 這種聽起來像“解釋沒有解釋”,但這是一個粗略的演練:
將set_ev_cls
視為裝飾器的工廠。 它是在調用裝飾器時捕獲參數的:
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
並返回一個函數_set_ev_cls_dec
,該函數的變量綁定到:
ev_cls = ofp_event.EventOFPSwitchFeatures dispatchers = CONFIG_DISPATCHER
換句話說,您現在擁有一個“定制”或“參數化”調度程序,它在邏輯上等同於:
def custom_decorator(handler): if 'callers' not in dir(handler): handler.callers = {} for e in _listify(ofp_event.EventOFPSwitchFeatures): handler.callers[e] = _Caller(_listify(CONFIG_DISPATCHER), e.__module__) return handler
(如果在調用@set_ev_cls(...)
時捕獲了ofp_event.EventOFPSwitchFeatures
和CONFIG_DISPATCHER
的值)。
所述custom_decorator
步驟1的被施加到_switch_features_handler
作為更傳統unparameterized裝飾器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.