装饰器进阶

装饰器的简单回顾

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

装饰器
开发原则:开放封闭原则
装饰器的作用:在不改变原函数的调用方式的情况下,在函数的前后添加功能
装饰器的本质:闭包函数

装饰器的模式

def wrapper(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 '好开心'

ret = holiday(3)
print(ret)

 

我们来看两个双下方法:__name__ 、__doc__

def wahaha():
   '''
   一个打印娃哈哈的函数
   '''
   print('娃哈哈')

print(wahaha.__name__)  #查看字符串格式的函数名
print(wahaha.__doc__)     #document 显示函数的注释(限于多行注释)
#输出结果:
'''
wahaha

   一个打印娃哈哈的函数

'''

 

接下来是 wraps 函数

from functools import wraps  #引用 wraps 函数

def wrapper(func):
    #wraps() 加在最内层函数正上方
    #@wraps(func)   #在不使用 wraps 函数时 返回结果: inner  inner 函数的注释
    @wraps(func)    #使用 wraps 函数来装饰 inner 函数 返回结果:holiday  只是一个放假通知
    def inner(*args,**kwargs):
        '''
         inner 函数的注释
        '''
        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 函数时,显示的为 inner 函数的名称
print(holiday.__doc__)   #当不调用 wraps 函数时,显示的为 inner 函数的注释

ret = holiday(3)    #在使用装饰器 wraps 函数时,并不影响 holiday 函数的使用
print(ret)          #这正是装饰器函数的特点
# 返回结果:
'''
在被装饰的函数执行之前做的事
放假休息 3 天
在被装饰的函数执行之前做的事
好开心
'''

 

假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?
一个一个的取消掉? 没日没夜忙活3天。。。
过两天领导想通了,再让你加上。。。

#装饰器的三层嵌套 为的是给装饰器传入变量
import time
#flage = False  #此处控制执行与否
flage = True
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flage:
                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_out(flage)  #timmer_out(flage) 表示 timmer_out(flage) == timmer
def func():         #@ 表示 @timmer 即:func == timmer(func)
    time.sleep(0.1)
    print("结束")

@timmer_out(flage)
def func2():
    time.sleep(0.1)
    print("结束")

func()
func2()

 

多个装饰器,装饰一个函数

def wrapper(func):
    def inner(*args,**kwargs):
        print("-----1-----")
        ret = func(*args,**kwargs)
        print("*****1*****")
        return ret
    return inner

def wrapper2(func):
    def inner2(*args,**kwargs):
        print("-----2-----")
        ret = func(*args,**kwargs)
        print("*****2*****")
        return ret
    return inner2

def wrapper3(func):
    def inner3(*args,**kwargs):
        print("-----3-----")
        ret = func(*args,**kwargs)
        print("*****3*****")
        return ret
    return inner3

@wrapper3
@wrapper2
@wrapper
def f():
    print("in f")
    return '就是这样'
print(f())
输出结果如下:
-----3-----
-----2-----
-----1-----
in f
*****1*****
*****2*****
*****3*****
就是这样

 

执行过成可参考下图

 day 12 - 1 装饰器进阶 Python

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄