Python 为什么第二个装饰师不';在完成第一个装修工的工作之前,他不能完成他的工作吗?

Python 为什么第二个装饰师不';在完成第一个装修工的工作之前,他不能完成他的工作吗?,python,decorator,Python,Decorator,我是个新手 现在我被一个装修工困住了 问题是为什么第二个装饰师不结束他的工作,但是,暂停一下。 为什么在完成第一个装潢师之后,第二个装潢师完成了他的工作 功能 def document_it(func): def new_function(*args, **kwargs): print('Running function:', func.__name__) print('Positional arguments:', args) prin

我是个新手

现在我被一个装修工困住了

问题是为什么第二个装饰师不结束他的工作,但是,暂停一下。 为什么在完成第一个装潢师之后,第二个装潢师完成了他的工作

功能

def document_it(func):
    def new_function(*args, **kwargs):
        print('Running function:', func.__name__) 
        print('Positional arguments:', args)
        print('Keyword arguments:', kwargs)
        result = func(*args, **kwargs)
        print('Result:', result)
        return result
    return new_function
第一种情况

@document_it
def add_ints(a, b):
    return a + b

add_ints(3, 5)
第一种情况结果:仔细查看运行功能

Running function: add_ints
Positional arguments: (3, 5)
Keyword arguments: {}
Result: 8
第二种情况

@document_it
@document_it
def add_ints(a, b):
    return a + b

add_ints(3, 5)
第二种情况结果:仔细看。运行函数:新函数是第一个

Running function: new_function #seems 2nd's
Positional arguments: (3, 5) #seems 2nd's
Keyword arguments: {} #seems 2nd's
Running function: add_ints #seems 1st's
Positional arguments: (3, 5) #seems 1st's
Keyword arguments: {} #seems 1st's
Result: 8 #seems 1st's
Result: 8 #seems 2nd's

为什么第二个装饰人没有完成他的工作(第二个装饰人没有打印他的结果),但突然第一个装饰人出现了?

装饰只是功能应用程序的语法糖。您的原始代码

@document_it
@document_it
def add_ints(a, b):
    return a + b

add_ints(3, 5)
相当于

def add_ints(a, b):
    return a + b

add_ints = document_it(document_it(add_ints))

add_ints(3, 5)
对装饰器的每次调用都会创建一个新函数,该函数包装并调用装饰函数


如果稍微修改装饰器:

def document_it(func):
    def new_function(*args, **kwargs):
        print('Running function:', func.__name__) 
        print('Positional arguments:', args)
        print('Keyword arguments:', kwargs)
        print('Function id: ', id(func))
        result = func(*args, **kwargs)
        print('Result:', result)
        return result
    return new_function

4558719888
是原始的未修饰函数,它实际上添加了两个数字
4558720032
是由“内部”修饰符创建的
new_函数,而
4558720608
是由“外部”修饰符创建的
new_函数
,这就是
add_ints
的名称现在的绑定对象。

请参阅嵌套修饰符为什么会这样做。如果您在开始和结束时使用两个不同的修饰符来打印不同的内容,这将有助于您了解python在代码中的执行路径;您正在将
document\u it
应用于
add\u ints
,然后将
document\u it
应用于第一个
document\u it
返回的函数。修饰是在定义函数时发生的,而不是在调用
add\u ints
时。此外,您的输出(应该作为文本包含在问题中,而不是包含在链接图像中)与此处定义的
document\u it
不对应,后者不产生输出,只调用包装函数。@chepner噢!那是我的错误。谢谢你帮助我。我刚把它修好。请你复习一下好吗?我注意到“result=func(*args,**kwargs)”很重要。为什么“result=func(*args,**kwargs)”调用包装函数?这不只是任务吗?我已经测试了其他代码。我终于明白了return在multipledecorator中是如何工作的。在进行原始测试后,返回更改
def document_it(func):def new_函数(*args,**kwargs):print('Running function:',func._name__)print('Positional arguments:',args)print('Keyword arguments:',kwargs)print('function id:',id(func))result=func(*args,**kwargs)print('result:',result*result)返回结果*结果返回新函数
>>> print(id(add_ints))
4558720608
>>> add_ints(3, 5)
Running function: new_function
Positional arguments: (3, 5)
Keyword arguments: {}
Function id:  4558720032
Running function: add_ints
Positional arguments: (3, 5)
Keyword arguments: {}
Function id:  4558719888
Result: 8
Result: 8