Python中的@decorators:为什么内部定义了函数?

Sin*_*dyr 2 python decorator

我刚刚开始使用Python,我刚刚接触过装饰器.我写了下面的代码,模仿我所看到的,它的工作原理:

def decorator_function(passed_function):
    def inner_decorator():
        print('this happens before')
        passed_function()
        print('this happens after')
    return inner_decorator

@decorator_function
def what_we_call():
    print('The actual function we called.')

what_we_call()
Run Code Online (Sandbox Code Playgroud)

但后来我写了这个,这会引发错误:

def decorator_function(passed_function):
    print('this happens before')
    passed_function()
    print('this happens after')

@decorator_function
def what_we_call():
    print('The actual function we called.')

what_we_call()
Run Code Online (Sandbox Code Playgroud)

那么,为什么我们需要在装饰器函数中包含内部嵌套函数?它的用途是什么?使用第二种语法不是更简单吗?我得不到什么?

有趣的是,BOTH具有相同(正确)的输出,但第二个也有错误文本,说"TypeError:'NoneType'对象不可调用"

请使用适合刚开始使用Python的语言和示例,这是他的第一个编程语言 - 也是OOP的新手!:) 谢谢.

mat*_*teo 5

原因是当你在decorator_function中包装what_we_call时:

@decorator_function
def what_we_call():
    ...
Run Code Online (Sandbox Code Playgroud)

你在做的是:

what_we_call = decorator_function(what_we_call)
Run Code Online (Sandbox Code Playgroud)

在你的第一个例子中它可以工作,因为你没有实际运行inner_function,你只是初始化它,然后你返回新的inner_function(稍后在调用装饰的what_we_call时调用):

def decorator_function(passed_function):
    def inner_decorator():
        print('this happens before')
        passed_function()
        print('this happens after')
    return inner_decorator
Run Code Online (Sandbox Code Playgroud)

相反,在你的第二个例子中,你将在两者之间运行2个print语句和passed_function(在我们的例子中是what_we_call):

def decorator_function(passed_function):
    print('this happens before')
    passed_function()
    print('this happens after')
Run Code Online (Sandbox Code Playgroud)

换句话说,您不会在之前的示例中返回一个函数:

what_we_call = decorator_function(what_we_call)
Run Code Online (Sandbox Code Playgroud)

你运行代码(你看到输出),然后decorator_function将'None'返回到what_we_call(覆盖原始函数),当你调用'None'时就好像它是一个函数Python抱怨.