2013-08-06 198 views
2

我有一个关于装饰器的问题。我明白了什么是装饰,我知道如何使用它,我已阅读所有本教程How to make a chain of function decorators?Python装饰器

我的理解是:

>>> def my_decorator(fn): 
>>>  print 'Do something before' 
>>>  print fn() 


>>> def foo(): 
>>>  return 'Hello World!' 

>>> foo = my_decorator(foo) 

是,同样的:

>>> def my_decorator(fn): 
>>>  print 'Do something before' 
>>>  print fn() 

>>> @my_decorator 
>>> def foo(): 
>>>  return 'Hello World!' 

我知道什么是闭包以及为什么我们在装饰器中使用闭参数(在嵌套函数中获取装饰器参数),但我不明白的是为什么我们使用闭包和嵌套函数来获取参数和函数。

闭包(或别的东西)如何访问参数和外部函数。没有@decorator,我无法做同样的事情。

这里有个例子我可以使用FOO()和函数的参数,而在参数传递这个函数:

def my_decorator(str): 
    def wrapper(fn): 
     def inner_function(*args): 
      print 'Do something before' 
      return fn(*args) 
     return inner_function 
    return wrapper 

@my_decorator('test') 
def foo(a, b): 
    return a + b 


print foo(1, 1) 

这怎么可能?

+0

因为这就是装饰者所做的事情。这不是一个简单的函数调用,它是一个装饰器,并且它作为第一个参数传递给它下面的函数(并且返回的函数将替换它)。 –

+0

这是神奇的? – Freelancer

+0

这完全不是魔术 - 这就像问一个函数后面的括号为什么叫它 - 它是该语言的文档化部分。 –

回答

-1

我找到了解决办法:

事实上装饰用闭合功能: 因此,这里的解决方案做同样的事情,没有装饰,并与参数(这只是易懂的操作,并学习)

def wrapper(str): 
    def decorator_factory(fn): 
     def inner_function(*args): 
      print 'Do something before' 
      return fn(*args) 
     return inner_function 
    return decorator_factory 

@my_decorator('test') 
def foo(a, b): 
    return a + b 

# with decorator 
print foo(1, 1) 

# without decorator 
print wrapper('str')(foo)(1, 1) 
+2

另一种查看方法是:'the_actual_decorator = my_decorator('some_string')'。你看,函数'my_decorator()'的命名有点差(对于这个例子),因为它本身并不是一个装饰器,而是一个封装器,它返回一个封闭装饰器。 *返回*装饰器是应用于'foo()'的装饰器。 –

+0

所以我必须在wrapper()中命名my_decorator()? – Freelancer

+0

我编辑了我的答案,谢谢 – Freelancer

-1

Decorator是一个接受一个参数的函数(这个参数是函数) - 这是我对装饰器的定义。在你的情况下,wrapper是装饰者。 my_decorator用于收集inner_function的参数。 inner_function用于替换原始[未装饰]功能。一步一步的解释是:

  1. my_decorator被称为收集选项inner_function
  2. my_decorator回报wrapper
  3. wrapper是负责捕捉原有功能或者换句话说装饰。在你的情况下,原始功能是foo。原创
  4. wrapper回报替换功能(这是inner_function
  5. 从现在fooinner_function,因此inner_function执行则foo

希望它使事情更清楚一点。

+0

感谢您的评论帮助我找到装饰器如何调用所有功能 – Freelancer