2

我有一个关于装饰器的问题。我了解什么是装饰器并且知道如何使用它,我已经阅读了本教程的所有内容如何制作函数装饰器链?

我明白那个 :

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

这怎么可能?

4

2 回答 2

-1

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

  1. my_decorator被调用来收集选项inner_function
  2. my_decorator返回wrapper
  3. wrapper负责捕获原始功能或装饰它。在您的情况下,原始功能是foo.
  4. wrapper返回原始的替换函数(即inner_function
  5. from nowfoo指向inner_function, 因此inner_function被执行 thenfoo被调用

希望它能让事情变得更清楚一些。

于 2013-08-06T13:37:13.820 回答
-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)
于 2013-08-06T13:46:58.793 回答