gpt4 book ai didi

Python 3 - 装饰器执行流程

转载 作者:行者123 更新时间:2023-12-01 01:38:16 25 4
gpt4 key购买 nike

下面的例子取自Python Cookbook第3版第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) ,我们得到decorate = .decorate at 0x000000000<内存地址>>

问题:为什么控件会返回执行“defdecorate”函数?是因为“decorate”函数在栈顶吗?

场景2:执行@attach_wrapper(wrapper)时,控件会执行attach_wrapper(obj, func=None)并部分执行函数返回 func =

问题:为什么控件会返回执行def Attach_wrapper(obj, func=None): 这次 func 的值是 *.decorate..set_message at 0x000000000 > 被传递给attach_wrapper?

最佳答案

场景 1

这个:

@logged(logging.DEBUG)
def add(x, y):
....

与此相同:

def add(x, y):
....
add = logged(logging.DEBUG)(add)

请注意,这里有两个调用:第一个 logged(logging.DEBUG) 返回 decorate,然后调用 decorate(add)

场景 2

场景 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)

<小时/>

换句话说...

loggedattach_wrapper 不是装饰器。这些是返回装饰器的函数。这就是为什么要进行两次调用:一次调用返回装饰器的函数,另一个调用装饰器本身。

关于Python 3 - 装饰器执行流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52174977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com