Python初学者第二十三天 函数进阶(2)装饰器

 装饰器:

需求----> 写一个功能,测试其他同事函数的调用效率。  

第一版:功能版

import time

def func():
    time.sleep(0.2)
    print('非常复杂')

def func1():
    time.sleep(0.3)
    print('超级复杂')

# print(time.time())
start_time = time.time()
func()
end_time = time.time()
print('此函数的执行效率为%s' % (end_time - start_time))
View Code

第二版:函数版

import time
def func():
    time.sleep(0.2)
    print('非常复杂')
func()
def func1():
    time.sleep(0.3)
    print('超级复杂')
def timmer(f):
    start_time = time.time()
    f()
    end_time = time.time()
    print('此函数的执行效率为%s' % (end_time - start_time))
timmer(func)
# timmer(func1)
# func()
func()
# 如果在实际项目中测试函数,
# 假如函数有1500个,那么你1500个timmer(func),工作量很大。
# 你要在不改变函数执行的指令下,同时测试效率。
View Code

第三版:在不改变被测函数的执行方式下,同时测试执行效率

import time

def func():
    time.sleep(0.2)
    print('非常复杂')
# func()
def func1():
    time.sleep(0.3)
    print('超级复杂')

def timmer(f):
    start_time = time.time()
    f()
    end_time = time.time()
    print('此函数的执行效率为%s' % (end_time - start_time))

timmer(func)
timmer(func1)
func()
f1 = func
func = timmer
func(f1)  # timer(func)
View Code

装饰器的雏形:

import time
def func():
    time.sleep(0.2)
    print('非常复杂')
# func()

def func1():
    time.sleep(0.3)
    print('超级复杂')
def timmer(f):
    def inner():
        start_time = time.time()
        f()
        end_time = time.time()
        print('此函数的执行效率为%s' % (end_time - start_time))
    return inner
# 语法糖 @
func = timmer(func)
func()
func1 = timmer(func1)
func1()
View Code

 

装饰器的优化: # timmer 就是装饰器: 在不改变原函数的调用指令情况下,给原函数增加额外的功能。

在被测函数上方@timmer 即添加装饰器。代码从上执行时,遇到@timmer 会往下走一层,相当于func = timmer(func)

import time

def timmer(f):
    def inner():
        start_time = time.time()
        f()
        end_time = time.time()
        print('此函数的执行效率为%s' % (end_time - start_time))
    return inner

@timmer # func = timmer(func)
def func():
    time.sleep(0.2)
    print('非常复杂')
func()
@timmer # func1 = timmer(func1)
def func1():
    time.sleep(0.3)
    print('超级复杂')

 

装饰器基础进阶1:带参数的装饰器  #*args,**kwargs 万能传参

import time

def timmer(f):
    def inner(*args,**kwargs):  # 函数的定义: * 聚合。args = (1,2,3,434545,4234.)
        # a1 = 'wusir'
        # b1 = 'alex'
        start_time = time.time()
        f(*args,**kwargs)  # 函数执行:* 打散。f(*(1,2,3,434545,4234.),)
        end_time = time.time()
        print('此函数的执行效率为%s' % (end_time - start_time))
    return inner

@timmer # func = timmer(func)
def func(a,b):
    time.sleep(0.2)
    print('非常复杂%s%s'% (a,b))
func('wusir','alex')  # inner()

装饰器基础进阶2:有返回值的装饰器  

import time

def timmer(f):  # f = func
    def inner(*args,**kwargs):
        start_time = time.time()
        ret = f(*args,**kwargs)  # func()
        end_time = time.time()
        print('此函数的执行效率为%s' % (end_time - start_time))
        return ret
    return inner

@timmer # func = timmer(func)
def func(a,b):
    time.sleep(0.2)
    print('非常复杂%s%s'% (a,b))
    return 666
ret = func('wusir','alex')  # inner()
print(ret)

@timmer # func = timmer(func)
def func(a,b,c):
    time.sleep(0.2)
    print('非常复杂%s%s%s'% (a,b,c))
func('wusir','alex','barry')  # inner()
装饰器用途:登录认证,打印日志等等。
总结:
其实装饰器本质是闭包,他的传参,返回值都是借助内层函数inner,
他之所以借助内层函数inner 就是为了让被装饰函数 在装饰器装饰前后,没有任何区别。
看起来没有变化。

装饰器的标准格式:
def auth(f): # f = func3函数名
    def inner(*args,**kwargs):  #万能传参
        ret = f(*args,**kwargs)
        return ret         #返回值
    return inner

@auth
def comment():
    print('欢迎来到评论页面')
comment()

posted @ 2018-01-30 22:43  摩柯无良  阅读(117)  评论(0编辑  收藏  举报