簡體   English   中英

裝飾員與參數

[英]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_clsdispatchers參數。

所以:

  • set_ev_cls_dev創建一個本地函數,並在其ev_clsdispatchers參數周圍返回一個閉包,並返回該函數。
  • 那封被稱為與_switch_features_handler作為它的參數,它會修改和添加一個返回參數callers屬性,它是一個字典_Caller從封閉在建對象dispatchers參數和鍵控關閉該封閉了ev_cls參數。

在不詳細說明內部發生什么的情況下解釋其工作原理? 這種聽起來像“解釋沒有解釋”,但這是一個粗略的演練:

  1. 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.EventOFPSwitchFeaturesCONFIG_DISPATCHER的值)。

  2. 所述custom_decorator步驟1的被施加到_switch_features_handler作為更傳統unparameterized裝飾器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM