理解python的装饰器中的函数包装器

时间:2018-04-23 13:35:36

标签: python decorator wrapper

我有两个python decorators实现的例子。我想知道它们之间在函数包装器实现方面有什么区别。他们以同样的方式工作?有任何背景差异?做函数包装器的pythonic方法是什么?

示例1

from functools import wraps

def retry(times=3, waiting_time=30):
    '''
    Decorator to retry any functions 'times' times.

    Parameters
    ----------    
    times: int
        Number of times to retry to execute
    waiting_time: int
        Number of times to wait between retries

    '''
    def retry_decorator(func):
        # My doubt is here.
        @wraps(func)
        def retried_function(*args, **kwargs):
            for i in range(times):
                try:                           
                    return func(*args, **kwargs)
                except Exception as err:
                    print(f'Try nº {i+1}')
                    sleep(waiting_time)           

            func(*args, **kwargs)

        return retried_function

    return retry_decorator

示例2

def exception(logger):
    '''
    Decorator that wraps the passed function and logs 
    exceptions when it occurs.

    Parameters
    ----------
    logger : logging object
        Object to use to log exceptions

    ''' 
    def decorator(func):
        # Here the function wrapper is different from example 1     
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                # log the exception
                err = "There was an exception in "
                err += func.__name__
                logger.exception(err) 
                # re-raise the exception
                raise
        return wrapper
    return decorator

1 个答案:

答案 0 :(得分:1)

首先,我们正在寻找比装饰者更复杂的东西。装饰器是一个将函数作为输入并返回函数的函数。这里,top函数返回装饰器。因此它们实际上也是上面意义上的装饰器,即使通常称为装饰器的是第一个内部函数。此定义方案通常可用于创建参数化装饰器。

有了这个,你似乎特意询问View。如果是这样,我只能敦促您查看文档https://docs.python.org/2/library/functools.html

基本上,它用于使装饰器返回的函数看起来与装饰函数相同,即:具有相同的名称,docstrings等...