[英]Python 3 - Decorators execution flow
以下示例摘自python Cookbook第三版9.5節。 我在每一行都放置了斷點,以了解執行流程。 以下是代碼示例,其輸出和我所遇到的問題。 我試圖解釋我的問題,如果您需要更多信息,請告訴我。
from functools import wraps, partial
import logging
# Utility decorator to attach a function as an attribute of obj
def attach_wrapper(obj, func=None):
if func is None:
return partial(attach_wrapper, obj)
setattr(obj, func.__name__, func)
return func
def logged(level, name=None, message=None):
def decorate(func):
logname = name if name else func.__module__
log = logging.getLogger(logname)
logmsg = message if message else func.__name__
@wraps(func)
def wrapper(*args, **kwargs):
log.log(level, logmsg)
return func(*args, **kwargs)
@attach_wrapper(wrapper)
def set_message(newmsg):
nonlocal logmsg
logmsg = newmsg
return wrapper
return decorate
# Example use
@logged(logging.DEBUG)
def add(x, y):
return x + y
logging.basicConfig(level=logging.DEBUG)
add.set_message('Add called')
#add.set_level(logging.WARNING)
print (add(2, 3))
輸出是
DEBUG:__main__:Add called
5
我了解裝飾器的概念,但這有點令人困惑。
方案1 。 當調試以下行@logged(logging.DEBUG)時 ,我們在0x000000000 <memoryaddress >>下獲得decorate = .decorate。
問題 :為什么控件會返回執行“ def decorate”功能? 是因為“裝飾”功能位於堆棧的頂部嗎?
方案2 :執行@attach_wrapper(wrapper)時 ,控件轉到執行attach_wrapper(obj,func = None) ,部分函數返回func =
問題 :為什么控件將返回執行def attach_wrapper(obj,func = None):這次將如何將func的值為* .decorate..set_message在0x000000000>傳遞給attach_wrapper?
這個:
@logged(logging.DEBUG)
def add(x, y):
....
與此相同:
def add(x, y):
....
add = logged(logging.DEBUG)(add)
請注意,這里有兩個調用:首先logged(logging.DEBUG)
返回decorate
,然后調用decorate(add)
。
與方案1中的相同:
@attach_wrapper(wrapper)
def set_message(newmsg):
...
與此相同:
def set_message(newmsg):
...
set_message = attach_wrapper(wrapper)(set_message)
同樣,有兩個調用:首先attach_wrapper(wrapper)
返回partial
對象,然后調用partial(set_message)
。
logged
和attach_wrapper
不是裝飾器。 這些是返回裝飾器的函數。 這就是為什么要進行兩次調用:一個調用返回裝飾器的函數,另一個調用裝飾器本身。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.