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

问题描述:

我刚刚开始使用Python,并且刚刚接触到装饰器。我写了下面的代码,模仿我所看到的,和它的作品:@decorators在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() 

但后来我写了这一点,这引发错误:

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() 

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

有趣的是,这两个具有相同的(正确)的输出,但在第二个有错误文本为好,说:“类型错误:‘NoneType’对象不是可调用的”

请用语言和例子适合对于刚开始使用Python的人来说,他的第一个编程语言 - 也是OOP的新手! :) 谢谢。

的原因是,当你做包装what_we_call在decorator_function:

@decorator_function 
def what_we_call(): 
    ... 

你在做什么是:

what_we_call = decorator_function(what_we_call) 

在你第一个例子中它的作品,因为你不跑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 

相反,在你的第二个例子中,你要运行在2个之间打印报表和passed_function(what_we_call在我们的例子):

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

换句话说,你不回的功能之前的例子:你运行

what_we_call = decorator_function(what_we_call) 

的代码(你可以看到输出),但随后decorator_function回报“无”到what_we_call(覆盖原来的功能),并且当你调用“无”,如果它是Python抱怨的一个函数。

+0

所以decorator_function仅仅是每当调用what_we_cal()时被调用的“引擎”,但inner_decorator是传回的实际函数?所以我可以通过返回回传任何东西,只要它是一个函数? – Sindyr

+0

PS:如何格式化评论中的代码块? – Sindyr

+0

所以你甚至可以写这个: 'def decorator_function(passed_function): return other_function' 并且完全修正装饰函数,是吗? – Sindyr

Python装饰器基本上只是语法糖。这:

@decorator 
def fn(arg1, arg2): 
    return arg1 + arg2 

变为这样:

def fn(arg1, arg2): 
    return arg1 + arg2 
fn = decorator(fn) 

也就是说,一个装饰基本上接受函数作为参数,并返回 “东西”;这个“东西”被绑定到装饰函数的名字上。

在几乎所有情况下,这个“something”应该是另一个函数,因为预计fn将是一个函数(并且可能会像调用它一样)。