前言

带参装饰器基于无参装饰器,比无参装饰器复杂,主要难点在于如何理清整个装饰器如何运作的。

示例

def logger(fn):
"""
接受一个函数对象,返回一个函数对象
"""
    def _logger(*args, **kwargs):
        print("Function {} Start...".format(fn.__name__))    # 打印函数开始执行日志
        ret = fn(*args, **kwargs)    # 开始执行函数
        # 注意这里是执行fn
        print("Function {} End.".format(fn.__name__))    # 函数结束
        return ret    # 返回函数执行后的结果
        # 此处不管原函数是否返回最好return一下,哪怕就只有一个None

@logger    # 该操作等价于  add = logger(add)
def add(x, y):
    return x + y

# 调用函数
sum = add(4 , 5)

这是一个无参装饰器,存在一个弊端就是被装饰的函数的属性在装饰后发生改变,此时我们可以用一个有参装饰器解决这以缺陷

def copy(src):
    """
    接受一个源函数,返回一个目标函数
    """
    def _copy(dst):
        dst.__name__ = src.__name__
        dst.__doc__ = src.__doc__
        # 修改目标函数的属性,然后返回一个目标函数
        return dst
    return _copy


def logger(fn):
"""
接受一个函数对象,返回一个函数对象
"""
    @copy(fn)
    # copy(fn)的执行结果为  => _copy(是一个函数对象)
    # @copy(fn) <==> @_copy ==> _logger = _copy(_logger)
    # 装饰_logger函数,返回一个新函数(_logger)
    def _logger(*args, **kwargs):
        print("Function {} Start...".format(fn.__name__))    # 打印函数开始执行日志
        ret = fn(*args, **kwargs)    # 开始执行函数
        # 注意这里是执行fn
        print("Function {} End.".format(fn.__name__))    # 函数结束
        return ret    # 返回函数执行后的结果
        # 此处不管原函数是否返回最好return一下,哪怕就只有一个None

@logger    # 该操作等价于  add = logger(add)
def add(x, y):
    """
    两个数加法函数
    :param x: 第一个数
    :param y: 第二个数
    :return: x+y
    """
    return x + y

# 调用函数
sum = add(4 , 5)
print(add(4,5), add.__doc__,sep='\n')
# 结果如下
# 9
#   两个数加法函数
#   :param x: 第一个数
#   :param y: 第二个数
#   :return: x+y
Last modification:June 10th, 2020 at 03:39 pm
If you think my article is useful to you, please feel free to appreciate