装饰器

不带参数完整的装饰器

被装饰函数的基本信息变成了装饰器返回的 wrapper 函数的信息

用wraps将被装饰函数的信息复制给 wrapper 函数 

from functools import wraps
import time

def timethis(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(func.__name__, end - start)

        return result
    return wrapper

@timethis
def fibonacci(n):
    """
    求斐波拉契数列第 n 项的值
    """
    a = b = 1
    while n > 2:
        a, b = b, a + b
        n -= 1
    return b

if __name__ == '__main__':
    a=fibonacci(100)
    print(a)

 带参数完整的装饰器

返回一个装饰器,这个返回的装饰器再去装饰 func 函数

def logged(level, name=None, message=None):
    def decorator(func):
        logname = name if name else func.__module__
        logmsg = message if message else func.__name__

        @wraps(func)
        def wrapper(*args, **kwargs):
            print(level, logname, logmsg, sep=' - ')
            return func(*args, **kwargs)
        return wrapper
    return decorator

@logged('debug', name='example', message='message')
def fun(*args, **kwargs):
    pass

def main():
    fun()
    
if __name__ == '__main__':
    main()

多功能装饰器

多个装饰器,按靠近函数的先执行,fun前面的执行顺序相反,fun里的靠近函数执行

from functools import wraps, partial
#partial函数作用:将所作用的函数作为partial()函数的第一个参数,原函数的各个参数依次作为partial()函数的后续参数
def logged(func=None, *, level='debug', name=None, message=None):
    if func is None:
        return partial(logged, level=level, name=name, message=message)

    logname = name if name else func.__module__
    logmsg = message if message else func.__name__

    @wraps(func)
    def wrapper(*args, **kwargs):
        print(level, logname, logmsg, sep=' - ')
        return func(*args, **kwargs)
    return wrapper

@logged
def func(*args, **kwargs):
    pass

@logged(level='debug', name='example', message='message')
def fun(*args, **kwargs):
    pass

def main():
    func()#有第一个参数值,不执行partial函数
    fun()#无第一个参数值,执行partial函数 即 执行logged(func=fun(),level='debug', name='example', message='message')
if __name__ == '__main__':
    main()

 

 

原文地址:https://www.cnblogs.com/luocodes/p/10691951.html