• python 装饰器



    # 装饰器 - @ - 拿到内层函数的引用 - 直接使用内层函数
    # 增强加法函数,输出被调用过及调用的参数
    def add(x, y):
    print("call fun {}, {}+{}".format(add.__name__, x, y)) # 输出到控制台
    return x + y
    print(add(4, 5))

    def add(x, y, file=None):
    print("call fun {}, {}+{}".format(add.__name__, x, y), file = file) # 输出到文件
    return x + y
    print(add(4, 5))

    # print 耦合太高
    # print 不属于加法业务
    # print 叫侵入式代码

    # 1 嵌套方式,避免侵入式代码
    print('------------------------')
    def add(x, y):
    return x + y

    def logger(fn):
    print('begin')
    x = fn(4, 5)
    print('end')
    return x
    print(logger(add))

    # 2
    def add1(x, y):
    return x + y

    def add2(x, y, z):
    return x + y + z

    def add3(x, y, *args, z, **kwargs):
    return x + y + z

    def logger(fn, *args, **kwargs): # 位置参数*args元组, 关键字参数**kwargs字典
    print('begin')
    x = fn(*args, **kwargs)
    print('end')
    return x
    print(logger(add1, 4, 5))
    print(logger(add2, 4, 5, 6))
    print(logger(add3, 4, z=5, y=6))

    # 3 柯里化
    def add1(x, y):
    return x + y

    def add2(x, y, z):
    return x + y + z

    def add3(x, y, *args, z, **kwargs):
    return x + y + z

    def logger(fn):
    def _logger(*args, **kwargs):
    print('begin')
    x = fn(*args, **kwargs)
    print('end')
    return x
    return _logger

    foo = logger(add1)
    print(foo(10, 10))

    print(logger(add1)(10, 100))

    add1 = logger(add1)
    print(add1(10, 1000))

    # 装饰器 @ ***
    def logger(fn):
    def _logger(*args, **kwargs):
    print('begin')
    x = fn(*args, **kwargs)
    print('end')
    return x
    return _logger # 返回内层函数的引用**

    @logger # 等价于add1 = logger(add1)
    def add1(x, y):
    return x + y

    print(add1(10, 10000))


    # 装饰器
    # 无参装饰器
    # 它是一个函数
    # 有一个函数作为它的形参
    # 返回值也是一个函数
    # 可以使用@functionname方式,简化调用
    # 装饰器是高阶函数,即传入函数,又返回函数

    import datetime
    import time
    def logger(fn):
    def wrap(*args, **kwargs):
    # before 功能增强
    print('args={}, kwargs={}'.format(args, kwargs))
    start = datetime.datetime.now()
    result = fn(*args, **kwargs)
    # after 功能增强
    duration = datetime.datetime.now() - start
    print('function {} took {}s.'.format(fn.__name__, duration.total_seconds()))
    return result
    return wrap # 返回内层函数的引用**

    @logger # 等价于 add = logger(add)
    def add(x, y):
    print('call add')
    time.sleep(2)
    return x + y

    print(add(10, 10000))

    # 装饰器理解 - 避免侵入式
    # 装饰器函数 > 前置功能增强 > 被增强函数 > 后置功能增强
    # 装饰器函数可以随意更换


    # 文档字符串
    # 在函数语句块的第一行,且吸管式多行文本,使用三引号
    # 惯例是首字母大写,第一行写概述,空一行,第三行写详细描述
    # 可以使用特殊属性__doc__访问这个文档

    def add(x, y):
    """
    This is a function
    :param x:
    :param y:
    :return:
    """
    result = x + y
    return result

    print(add(10, 10))
    print(add.__name__, add.__doc__, sep=' ')
    print('----------------------------------')

    # 文档字符串和装饰器
    # 解决被装函数的文档字符串无法显示问题
    import datetime
    import time

    def copyProperties(src, dest): # 包装函数和被包装函数字符文档统一
    dest.__name__ = src.__name__
    dest.__doc__ = src.__doc__

    def logger(fn):
    def wrap(*args, **kwargs):
    """
    This is wrapper
    """
    # before 功能增强
    print('args={}, kwargs={}'.format(args, kwargs))
    start = datetime.datetime.now()
    result = fn(*args, **kwargs)
    # after 功能增
    duration = datetime.datetime.now() - start
    print('function {} took {}s.'.format(fn.__name__, duration.total_seconds()))
    return result
    copyProperties(fn, wrap)
    return wrap # 返回内层函数的引用**

    @logger # add = logger(add)
    def add(x, y):
    """
    This is a function
    :param x:
    :param y:
    :return:
    """
    result = x + y
    return result

    print(add(10, 10000))
    print(add.__name__, add.__doc__, sep=' ')

    # 带参装饰器***
    import datetime
    import time

    def copyProperties(src): # 包装函数和被包装函数字符文档统一
    def copyWrap(dest):
    dest.__name__ = src.__name__
    dest.__doc__ = src.__doc__
    return dest
    return copyWrap

    def logger(fn):
    # @copyProperties(fn)
    # 1 先不看@符号,返回copyWrap
    # 2 @copyProperties(fn) 将其下面的函数(logWrap)作为参数,再拿到logWrap对象
    @copyProperties(fn) # wrap = copyWrap(logger.wrap) 带参装饰器***
    def logWrap(*args, **kwargs):
    """
    This is wrapper
    """
    # before 功能增强
    print('args={}, kwargs={}'.format(args, kwargs))
    start = datetime.datetime.now()
    result = fn(*args, **kwargs)
    # after 功能增
    duration = datetime.datetime.now() - start
    print('function {} took {}s.'.format(fn.__name__, duration.total_seconds()))
    return result
    return logWrap # 返回内层函数的引用**

    @logger # add = logger(add)
    def add(x, y):
    """
    This is a function
    :param x:
    :param y:
    :return:
    """
    result = x + y
    return result

    print(add(10, 10000))
    print(add.__name__, add.__doc__, sep=' ')

    # 通过copyProperties函数将被包装函数的属性覆盖掉包装函数
    # 凡是被装饰的函数都需要复制这些属性,这个函数很通用
    # 可以将复制属性的函数构建成装饰器函数,带参装饰器

    # 过滤执行时间过长的函数**
    import datetime
    import time

    def logger(time):
    def __logger(fn):
    def wrap(*args, **kwargs):
    # before 功能增强
    start = datetime.datetime.now()
    result = fn(*args, **kwargs)
    # after 功能增强
    duration = (datetime.datetime.now() - start).total_seconds()
    if duration > time:
    print('function {} took too long time -> {}s.'.format(fn.__name__, duration))
    return result
    return wrap # 返回内层函数的引用**
    return __logger

    @logger(3) # 等价于 add = logger(3)(add),其中logger(3)返回的是__logger
    def add(x, y):
    print('call add')
    time.sleep(5)
    return x + y

    print(add(4, 5))



    # 过滤执行时间在一定范围内的函数**
    import datetime
    import time

    def logger(time1, time2):
    def __logger(fn):
    def wrap(*args, **kwargs):
    # before 功能增强
    start = datetime.datetime.now()
    result = fn(*args, **kwargs)
    # after 功能增强
    duration = (datetime.datetime.now() - start).total_seconds()
    if duration > time1 and duration < time2:
    print('function {} took too long time -> {}s.'.format(fn.__name__, duration))
    return result
    return wrap # 返回内层函数的引用**
    return __logger

    @logger(3, 10) # 等价于 add = logger(3)(add),其中logger(3)返回的是__logger
    def add(x, y):
    print('call add')
    time.sleep(6)
    return x + y

    print(add(4, 5))

    # 带参装饰器
    #  它是一个函数
    #  函数作为它的形参
    #  返回值是一个不带参的装饰器函数
    #  使用@functionname(参数列表)方式调用
    #  可以看到在装饰器外层又加了一层函数

    # 实践:替换print,以便输出到其他存储***

    import datetime
    import time

    def copyProperties(src): # 包装函数和被包装函数字符文档统一
    def copyWrap(dest):
    dest.__name__ = src.__name__
    dest.__doc__ = src.__doc__
    return dest
    return copyWrap

    def logger(duration, func=lambda name, delta:print('function {} took too long time -> {}s.'.format(name, delta))):
    def __logger(fn):
    # @copyProperties(fn)
    # 1 先不看@符号,返回copyWrap
    # 2 @copyProperties(fn) 将其下面的函数(logWrap)作为参数,再拿到logWrap对象
    @copyProperties(fn) # wrap = copyWrap(logger.wrap) 带参装饰器***
    def logWrap(*args, **kwargs):
    """
    This is wrapper
    """
    # before 功能增强
    start = datetime.datetime.now()
    result = fn(*args, **kwargs)
    # after 功能增
    delta = (datetime.datetime.now() - start).total_seconds()
    if delta > duration:
    func(fn.__name__, delta)
    return result
    return logWrap # 返回内层函数的引用**
    return __logger

    @logger(3) # add = logger(add)
    def add(x, y):
    """
    This is a function
    :param x:
    :param y:
    :return:
    """
    time.sleep(5)
    result = x + y
    return result

    print(add(10, 10000))
  • 相关阅读:
    hdu4930 模拟斗地主
    hdu4930 模拟斗地主
    hdu4923 f(A,B)分段处理
    hdu4923 f(A,B)分段处理
    poj2112 二分最大流+Floyd
    poj2112 二分最大流+Floyd
    POJ1149 PIGS(最大流)
    POJ1149 PIGS(最大流)
    对最大团的理解
    对最大团的理解
  • 原文地址:https://www.cnblogs.com/lizitest/p/9614511.html
Copyright © 2020-2023  润新知