python学习day11 day12 装饰器

装饰器是一种特殊的闭包,它是嵌套函数,也调用了外部函数的变量,只不是调用的是外部函数的形参。

用于装饰函数

装饰器的作用 —— 不想修改函数的调用方式 但是还想在原来的函数前后添加功能
timmer就是一个装饰器函数,只是对一个函数 有一些装饰作用

原则: 开放封闭原则
开放 : 对扩展是开放的
封闭 : 对修改是封闭的


装饰器的固定模式:
def wrapper(f):    #装饰器函数,参数为被装饰的函数
    def inner(*args,**kwargs):  #参数为被装饰函数的原始参数
        '''在被装饰函数之前要做的事'''
        ret = f(*args,**kwargs)    #被装饰的函数,ret是被装饰函数的返回值
        '''在被装饰函数之后要做的事'''
        return ret   #返回inner中的值  也就是装饰后的东西
    return inner   #返回inner的名字

@wrapper         #语法糖 @装饰器函数名
def func(a,b):     #被装饰的函数
    time.sleep(0.01)
    print('老板好同事好大家好',a,b)
    return '新年好'

ret = func(1,2) #实际上执行的是inner(1,2) 也就是装饰后的函数

 

 

 

应用:

自定义函数func的执行时间+0.01s

import time

def wapper(f):    #定义一个装饰器
    def inner(*args,**kwargs):
        start = time.time()
        ret = f(*args,**kwargs)
        end = time.time()
        t = end - start
        return ret, t
    return inner

@wapper
def func(a,b='zepei'):
    c = 70 + a
    return b,c

print(func(2,b='fan'))   #(('fan', 72), 0.010000228881835938)  

装饰器进阶

wraps

from functools import wraps
def wrapper(func):  #func = holiday
    @wraps(func)
    def inner(*args,**kwargs):
        print('在被装饰的函数执行之前做的事')
        ret = func(*args,**kwargs)
        print('在被装饰的函数执行之后做的事')
        return ret
    return inner

@wrapper   #holiday = wrapper(holiday)
def holiday(day):
    '''这是一个放假通知'''
    print('全体放假%s天'%day)
    return '好开心'

print(holiday.__name__) # 加了wraps后  此处打印的是holiday的名字
print(holiday.__doc__) # 打印holiday的解释文档
ret = holiday(3)   #inner
print(ret)

带参数的装饰器

 外面再加入一个嵌套,判断是否使用装饰器

import time
FLAGE = False   #如果是False 不装饰函数
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag:
                start = time.time()
                ret = func(*args,**kwargs)
                end = time.time()
                print(end-start)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer
# timmer = timmer_out(FLAGE)
@timmer_out(FLAGE)    #wahaha = timmer(wahaha)
def wahaha():
    time.sleep(0.1)
    print('wahahahahahaha')

@timmer_out(FLAGE)
def erguotou():
    time.sleep(0.1)
    print('erguotoutoutou')

wahaha()
erguotou()

  

 

多个装饰器装饰一个函数

两个装饰器详解:

 

 

 三个装饰器:

def wrapper1(func):
    def inner1():
        print('wrapper1 ,before func')
        ret = func()  #func=f
        print('wrapper1 ,after func')
        return ret
    return inner1
def wrapper2(func):
    def inner2():
        print('wrapper2 ,before func')
        ret = func()  #func=inner1
        print('wrapper2 ,after func')
        return ret
    return inner2
def wrapper3(func):
    def inner3():
        print('wrapper3 ,before func')
        ret = func()  #func=inner2
        print('wrapper3 ,after func')
        return ret
    return inner3

@wrapper3   # f=wrapper3(f)=wrapper3(inner2)=inner3
@wrapper2   # f=wrapper2(f)=wrapper2(inner1)=inner2
@wrapper1   # 先执行这个语法糖 f=wrapper1(f)=inner1
def f():
    print('in f')
    return '哈哈哈'

f()  # inner3()
'''
输出:
wrapper3 ,before func
wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func
wrapper3 ,after func
'''

#如果执行下面的,会打印f的输出
print(f())
'''
输出:
wrapper3 ,before func
wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func
wrapper3 ,after func
哈哈哈
'''

  

 

posted @ 2018-10-23 21:06  xyfun72  阅读(120)  评论(0编辑  收藏  举报