python函数的装饰器

装饰器

装饰器的本身也是一个函数,它可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象,就是函数装饰函数的这样的一个过程。
装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。

装饰器的形成

比如,测试一个函数的执行时间,在不改变原有代码的情况下,实现这个功能

简单装饰器

import time
def func1():
    print('this is func1')
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner
func1 = timer(func1)
func1()

但是这样还是有一个不好的地方,就是只要我们要实现这个功能,就有有这样一句话func1 = timer(func1),这样就会有点麻烦:就产生了一个叫语法糖的东东,是什么呢?

语法糖

import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner
    
@timer   #==> func1 = timer(func1)
def func1():
    print('in func1')
    
func1()

带参数的装饰器

def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def func1(a):
    print(a)

func1(1)

带动态参数的装饰器

import time
def wrapper(func):
    def inner(*args, **kwargs): 
        start_time = time.localtime()
        time_now = time.strftime("%Y-%m-%d %H:%M:%S", start_time)
        with open('log', encoding='utf-8', mode='a') as f1:
            f1.write("在%s是时间,执行了%s函数\n" % (time_now, func._name_))
            ret = func(*args, **kwargs)
            return ret
        return inner()
 
@wrapper
def func1():
    time.sleep(1)
    print(555)
@wrapper
def func2():
     time.sleep(2)
     print(666)
func1()
func2()

查看函数信息的方法

def index():
    '''这是一个主页信息'''
    print('from index')
 
print(index.__doc__)    #查看函数注释的方法
print(index.__name__)   #查看函数名的方法

例如:

from functools import wraps
 
def demo(func):
    @wraps(func)    #@wraps要加载最内层函数的正上方
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return  wrapper
@demo
def index():
    '''你以为这是什么就是个注释而已'''
    print('this is index')
print(index.__doc__)
print(index.__name__)

开放封闭的原则

装饰器遵循开放封闭的原则
1.对扩展是开放的,也就是说,必须允许代码扩展、添加新功能。
2.对修改是封闭的,尽可能的如果再次修改,不会影响别人的使用。

装饰器的主要功能和固定结构

'''装饰器的固定结构'''
def timer(func):
    def inner(*args, **kwargs):
        '''执行函数之前要做的'''
        re = func(*args, **kwargs):
        return re
'''wraps版'''
from functools import wraps
 
def demo(func):
    @wraps(func)    #@wraps要加载最内层函数的正上方
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return  wrapper

带参数的装饰器

	
def outer(flag):
    def timer(func):
        def inner(*args, **kwargs):
            if flag:
                print('执行函数之前要做的')
            re = func(*args, **kwargs)
             
            if flag:
                print('执行函数之后要做的')
            return re
        return inner
    return timer
@outer(False)
def func():
    print('6666')
 
func()

多个装饰器装饰一个函数

def wrapper1(func):
    def inner():
        print('wrappers1,before func')
        func()
        print('wrappers1,after func')
    return inner
 
def wrapper2(func):
    def inner():
        print('wrappers2,before func')
        func()
        print('wrappers2,after func')
    return inner
 
@wrapper1
@wrapper2
def f():
    print('in f')
 
f()

猜你喜欢

转载自blog.csdn.net/qq_38362416/article/details/83244732