python之路15--装饰器-all

一、装饰器说明

1、装饰器的作用:

                             在不改变原来函数的调用方式的情况下 在这个函数的前后添加新的功能

2、装饰器完美的符合了开放封闭的开发原则,

         对扩展是开发的
         对修改是封闭的

3、装饰器与闭包函数的区别

        闭包函数不一定是装饰器

        装饰器函数一定是闭包函数 

二、装饰器的语法

1、写一个计算一个函数执行时间的基础装饰器

import time
def budao():         #1、定义执行函数
    time.sleep(0.01)
    print("welcome to budaozhe.co")
def budaozhe(f):     #2、定义装饰器函数(f)为形参接收budao的内存地址
    def vip():       #4、定义了函数里的函数
        start = time.time()
        f()
        end = time.time()
        print(end - start)
    return vip       #5、将自己的内存地址作为返回值
budao = budaozhe(budao)    #3、执行budaozhe函数并将budao函数的内存地址传给budaozhe函数的形参并接收返回值vip(即此时budaob变量是函数vip的内存地址)
budao()                 #此时执行的是vip函数

执行结果:

welcome to budaozhe.co
0.01099395751953125

画图说明:

2、装饰器的语法糖写法与带参数函数的装饰器

import time
def budaozhe(f):     #定义装饰器函数
    def vip(a):       #4、定义了函数里的函数
        start = time.time()
        ret = f(a)
        end = time.time()
        print(end - start)
        return ret
    return vip       #5、将自己的内存地址作为返回值
@budaozhe           #语法糖的写法:它的位置必须紧挨着被装饰的函数,@装饰器函数,最终执行的意思是:budao = budaozhe(budao)
def budao(a):         #被装饰的函数,带有形参
    time.sleep(0.01)
    print("welcome to budaozhe.co",a)
    return "huanying"

a = budao(1)                 #此时执行的是vip函数
print(a)

执行结果:

welcome to budaozhe.co 1
0.01002049446105957
huanying

画图说明:

3、装饰带多个位置参数和关键字参数函数的装饰器

 

import time
def budaozhe(f):     #定义装饰器函数
    def vip(*args,**kwargs):       #4、定义了函数里的函数
        start = time.time()
        ret = f(*args,**kwargs)
        end = time.time()
        print(end - start)
        return ret
    return vip       #5、将自己的内存地址作为返回值
@budaozhe           #语法糖的写法:它的位置必须紧挨着被装饰的函数,@装饰器函数,最终执行的意思是:budao = budaozhe(budao)
def budao(a,b):         #被装饰的函数
    time.sleep(0.01)
    print("welcome to budaozhe.co",a,b)
    return "huanying"

@budaozhe           #语法糖的写法:它的位置必须紧挨着被装饰的函数,@装饰器函数,最终执行的意思是:budao = budaozhe(budao)
def budao1(a):         #被装饰的函数
    time.sleep(0.01)
    print("welcome to budaozhe.co",a)
    return "huanying"

#budao = budaozhe(budao)    #3、执行budaozhe函数并将budao函数的内存地址传给budaozhe函数的形参并接收返回值vip(即此时budaob变量是函数vip的内存地址)
a = budao1(1)                 #此时执行的是vip函数
a1 = budao(1,b = 2)                 #此时执行的是vip函数
print(a,'分割符',a1)

执行结果:

welcome to budaozhe.co 1
0.010038375854492188
welcome to budaozhe.co 1 2
0.010995149612426758
huanying 分割符 huanying

画图说明:

4、wraps使用

前面写的几个函数虽然调用方式还是和之前的调用方式一样,但是实际步骤还是走了装饰器的媒介,下面看下使用wraps实现原函数和装饰的功能互不影响的方法

from functools import wraps
def wrapper(func):
    @wraps(func)            #@wraps为固定格式,(func)为wrapper传进来的
    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__)         #结果为:holiday
print(holiday.__doc__)            #结果为:这是一个放假通知
ret = holiday(3)                      #结果为:全体放假3天
print(ret)                                #结果为:好开心

执行结果:

holiday

    这是一个放假通知
    
装饰之前做的事
全体放假3天
装饰之后做的事
好开心

画图说明:

5、带参数的装饰器

装饰器最多只能三层函数嵌套

实现需求说明:

         多个函数,再需要的时候开启装饰器,不需要时关闭装饰器,
import time
FLAGE = True
def wrapper_out(flag):
    def wrapper(func):
        def inner(*args,**kwargs):
            if flag == True:
                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 wrapper
@wrapper_out(FLAGE)
def yisou1():
    print("welcome to www.yisou.co")
    time.sleep(0.2)
@wrapper_out(FLAGE)
def yisou2():
    print("上易搜,了解每天新鲜事")
    time.sleep(0.2)
yisou1()
yisou2()

执行结果:

welcome to www.yisou.co
0.2008812427520752
上易搜,了解每天新鲜事
0.20087575912475586

画图说明:

6、多个装饰器装饰同一个函数

def wrapper1(f):
    def inner1():
        print("wrapper1 function frond")
        f()
        print("wrapper1 function end")
    return inner1

def wrapper2(f):
    def inner2():
        print("wrapper2 function frond")
        f()
        print("wrapper2 function end")
    return inner2

@wrapper2
@wrapper1        #func = wrapper1(func)
def func():
    print("this is function")
func()

执行结果:

wrapper2 function frond
wrapper1 function frond
this is function
wrapper1 function end
wrapper2 function end

 

画图说明:

 

 

 

 

 

 




posted @ 2018-08-04 18:50  欧-阳  阅读(132)  评论(0)    收藏  举报