在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Python/ python修飾器中被修飾函數帶參數的執(zhí)行過程

python修飾器中被修飾函數帶參數的執(zhí)行過程

這是 tornado.web.py 文件中一段

@property
def cookies(self):
    """An alias for `self.request.cookies <.httputil.HTTPServerRequest.cookies>`."""
    return self.request.cookies

這個 cookie 函數是在一個類里面,這個 self 應該是調用這個 cookie 的那個對象
比如 a.cookies(),self 就是那個 a。
那么 cookies 作為修飾函數
比如修飾函數形式是這樣(我在那個源碼文件中沒找到 property 這個函數。。)

def property(f1):
    def wrapper():
        ..
        return f1()
    return wrapper

則調用 cookies <=> 調用 property(cookies)
那么這個被修飾函數的參數 self 是怎么傳進這個修飾函數里面的呢


ps: 我為什么在源碼文件中沒有找到那個 property() 修飾函數,我都用 ctrl+f 找也沒找到
tornado.web.py源碼地址

回答
編輯回答
朕略傻

你如果對於 decorator 還有疑問的話, 可以參考 這篇文章

關於 decorator, 基本上一共有三個函數:

  1. decorator: 裝飾器/修飾器/修飾函數

  2. orifunc: 原函數/被修飾函數

  3. wrapper: 新函數/取代函數

簡單地可以表達為:

def decorator(orifunc):
    # do something here (register...)
    def wrapper(*args, **kwargs):
        # do something before (preprocess)
        result = orifunc()
        # do something after (postprocess)
        return result
    return wrapper

他們的關係是:

wrapper = decorator(orifunc)

可以用甜頭寫法表示為:

@decorator
def orifunc(*args, **kwargs):
    # do something...

decorator 在執(zhí)行裝飾的時候,只會將 orifunc 包裝並回傳, 其實就是用 wrapper 取代掉。

修飾這個步驟呼叫的的是 decorator, 傳遞的參數是 orifunc, 返回值是 wrapper, 這個時候 orifunc (或是他的包裝替代品 wrapper 都還沒被呼叫, 只有 decorator 被呼叫), 所以原函數 orifunc 的參數根本不會傳遞進修飾函數(decorator) 中。

只有當我們呼叫裝飾過後的函數 wrapper 時才需要傳入 orifunc 需要的參數 (orifuncwrapper 的參數介面應當一致)。

回到你的問題, 當 property 被呼叫的時候, 調用的函數是 property, 傳入的參數是原函數 cookies, 返回值是 wrapper, 這時跟 self 都還沒有關係。

當我們呼叫被修飾過的函數 wrapper(也就是property(cookies)) 才需傳入與 cookies 相同的參數, 此時 self 才被傳入。

self.cookies() <=> property(cookies)(self)
                   ^^^^^^^^^^^^^^^^^
                   修飾的這步尚與 self 無關
               <=> wrapper(self)
                   ^^^^^^^^^^^^^
                   調用 wrapper 時才與 self 有關

P.S. property 是 python 的內建函數, 並非 tornado 特有的東西, 你可以在 python doc 中找到說明。


我回答過的問題: Python-QA

2017年1月27日 15:57