標籤:部分 oca span target tle .com cti tar hub
看《Python cookbook》的時候,第9.5部分,“定義一個屬性可由使用者修改的裝飾器”,有個裝飾器理解起來花了一些時間,做個筆記免得二刷這本書的時候忘了
完整代碼:https://github.com/blackmatrix7/python-learning/blob/master/python_cookbook/chapter_9/section_5/attach_wrapper.py
書中的裝飾器(書中稱之為訪問器函數)
def attach_wrapper(obj, func=None): if func is None: return partial(attach_wrapper, obj) setattr(obj, func.__name__, func) return func
這個訪問器函數,接受兩個參數,obj是需要處理的對象,func是被裝飾的函數。實現的效果是將被裝飾的對象,附加到obj中,使obj這個對象具有func這個方法。
當訪問器函數,執行到func is None時,實際上是執行的是attach_wrapper(obj=wrapper),剛剛將需要處理的對象obj傳入。
@attach_wrapper(wrapper) def set_message(newmsg): print(‘set message‘) nonlocal logmsg logmsg = newmsg
用過裝飾器的話,一定可以知道,上面的set_message的裝飾器,實際上等於下面的方法
attach_wrapper(wrapper)(set_message)
對上面這個語句,還可以繼續拆分
訪問器函數中判斷,當func為None時,返回一個偏函數 return partial(attach_wrapper, obj)
這個偏函數實際上是產生了一個封裝器,封裝器本身接受被裝飾的函數。
所以我們得到一個偏函數,也是封裝器
partial_func = attach_wrapper(wrapper)
因為偏函數已經帶有一個obj參數, 所以再次調用時,執行 setattr(obj, func.__name__, func)
此時給裝飾器傳入的對象,附加上被裝飾的函數
partial_func(set_message)
如果還不明白,可以看下面的裝飾器。
這個裝飾器的功能,等價於上面的訪問器函數
def my_attach_wrapper(obj): """ 如果這樣寫就非常容易理解了,把這個方法附加到被傳入的對象中 :param obj: :return: """ def _my_attach_wrapper(func): setattr(obj, func.__name__, func) return _my_attach_wrapper
《Python cookbook》 “定義一個屬性可由使用者修改的裝飾器” 筆記