装饰器


装饰器的底层原理:装饰器用到了函数名的本质和闭包;    函数名本质:函数名可以做参数,也可以做返回值

import time
#不改变使用者调用方式的情况下,能够添加上这个计算时间功能
def timer(func_name):
    def inner():
        start=time.time()
        print('func_name',func_name)
        func_name()
        print(time.time()-start)
    print('inner',inner)
    return inner

def func1():
    sum_num=0
    for i in range(1000000):
        sum_num+=i
    print(sum_num)


def func2():
    sum_num = 0
    for i in range(1000000):
        sum_num += i

func1=timer(func1)
print('func1',func1)
func1()

进一步优化,有参数的

#函数是有参数的
def timer(func_name):
    def inner(*args,**kwargs):
        start=time.time()
        ret=func_name(*args,**kwargs)
        print(time.time()-start)
        return ret
    return inner

def func1(m,n):
    sum_num=0
    for i in range(1000000):
        sum_num+=i
    return sum_num

def func2():
    sum_num = 0
    for i in range(1000000):
        sum_num += i
    return sum_num

func1=timer(func1)
ret1=func1(666,n=123)
print(ret1)
func2=timer(func2)
ret2=func2()
print(ret2)

最终优化版

def timer(func_name):
    def inner(*args,**kwargs):
        start=time.time()
        ret=func_name(*args,**kwargs)
        print(time.time()-start)
        return ret
    return inner

@timer
def func1(m,n): #n和实参里的要一致
    sum_num=0
    for i in range(m):
        sum_num+=i
    return sum_num

@timer
def func2():
    sum_num = 0
    for i in range(1000000):
        sum_num += i
    return sum_num


ret1=func1(666,n=123)  #n和func1里的n要一样,对应
print(ret1)

ret2=func2()
print(ret2)
#什么时候用?
# 开放封闭原则:
# 开放原则:对拓展是开放的(比如,我写一个程序,后期增加功能,这些拓展开放的)
# 封闭原则:对修改是封闭的(已经开发好的功能,已经上线了,一般没特殊情况不会让你改)

#在已经写好的发版程序的基础上,需要对一个函数执行前后增加功能的时候,我们就要用装饰器

装饰器固定格式

def wapper(func):
    def inner(*args,**kwargs):
        '''在执行被装饰的函数之前要做的事'''
        '''比如判断是否登录'''
        ret=func(*args,**kwargs)
        '''在之前被装饰的函数之后要做的事'''
        '''比如写日志'''
        return ret
    return inner


@wapper
def func1():
    pass

func1()