2015-04-06 79 views
2

我想弄清楚为什么我需要一个更多的嵌套函数,当使用装饰器。这里是一个例子:python装饰器,嵌套函数

def func(f): 
    def deco(*args, **kwargs): 
     return f(*args, **kwargs) 
    return deco 

@func 
def sum(a, b): 
    return a+b 

print sum(5, 10) 

代码工程,一切都很好。但为什么我需要创建嵌套的“装饰”功能? 让我们试试没有它:

def func(f): 
    return f(*args, **kwargs) 

@func 
def sum(a, b): 
    return a+b 

print sum(5, 10) 

代码失败。

因此,有三个问题:

  1. 为什么第二个样本不工作?
  2. 如果我们使用嵌套函数,为什么args,kwargs会“神奇地”出现?
  3. 我能做些什么,使第二个样本工作?除了嵌套另一个功能,当然。
+3

装饰者应该返回一个函数而不是函数的结果。在你的第一个例子中,它返回一个函数...在第二个例子中,它返回你函数f返回的任何东西。 –

+1

那么第二个和第三个问题呢? – user

+0

'* args'和'** kwargs'不会“神奇地”出现,只有在您调用装饰函数后才会定义参数(http://stackoverflow.com/questions/36901/what-does-double-star -and-star-do-for-python-parameters) –

回答

3
  1. 为什么第二个样本不起作用?

    因为您正在调用返回函数,所以您没有返回函数。

  2. 如果我们使用嵌套函数,为什么args,kwargs会“神奇地”出现?

    它们不会出现神奇,我们宣布它们,如:

    def deco(*args, **kwargs): 
    

    这些都是通用的,并会匹配任何函数签名(参数列表)。你不必称之为argskwargs,这只是一个约定,你可以称它们为sharontracy

  3. 我能做些什么,使第二个样本工作?除了嵌套另一个功能,当然。

    那么你没有说你期望第二个样本做什么。但我想把它变成一个装饰者然后:

    def func(f): 
        return f 
    

    但是这并没有做很多!

顺便说一句,它通常是一个坏主意,覆盖现有的Python内建(sum) - 你必须有一个很好的理由。