一、装饰器

  1、简单装饰器

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 Java转python第四天 随笔 第1张
'''
    装饰器
'''
import time
def timer(func):
    def inner():
        start = time.time()
        time.sleep(1)
        re = func()
        print(time.time() - start)
        return re
    return inner
def func1():
    print(1)
func1 = timer(func1)
func1()
简单装饰器

  2、语法糖  

  当有很多方法需要加装饰器时,不需要在每次调用函数前执行func = timer(func)

  只需要在函数前加一个语法糖

Java转python第四天 随笔 第3张
'''
    装饰器:使用@timer
'''
import time
def timer(func):
    def inner():
        start = time.time()
        time.sleep(1)
        re = func()
        print(time.time() - start)
        return re
    return inner
@timer
def func1():
    print(1)
func1()
装饰器:使用@timer

  3、对有参方法加装饰器:

Java转python第四天 随笔 第5张
'''
    装饰器-单参数
'''
import time
def timer(func):
    def inner(a):
        start = time.time()
        time.sleep(1)
        re = func(a)
        print(time.time() - start)
        return re
    return inner
@timer
def func1(a):
    a+=10
    print(a)
func1(1)
'''
    装饰器-动态参数
'''
import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        time.sleep(0.01)
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner
l = {"a":1,"b":2}
@timer
def func1(*b,**l):
    return b[0]+b[1]+l.get("b")
print(func1(1,2,**l))
装饰有参函数

二、装饰器进阶

  1、固定格式

Java转python第四天 随笔 第7张
'''
    装饰器的固定格式
'''
def wrapper(func):
    def inner(*args,**kwargs):
        '''执行函数前的操作'''
        res = func(*args,**kwargs)
        '''执行函数后要做的'''
        return res
    return inner
@wrapper
def func():
    print(1)
func()
简单装饰器固定格式

  2、解决使用装饰器时导致函数的内置方法不能使用:

Java转python第四天 随笔 第9张
'''
    装饰器的固定格式,不改变原始全局中的原始函数
'''
from functools import wraps
def wrapper(func):
    @wraps(func)
    def inner(*args,**kwargs):
        '''执行函数前的操作'''
        res = func(*args,**kwargs)
        '''执行函数后要做的'''
        return res
    return inner
@wrapper
def func():
    '''函数内的注释'''
    print(1)
func()
print(func.__name__)
print(func.__doc__)
不改变原始全局中的原始函数

  3、带参数的装饰器,三层嵌套

Java转python第四天 随笔 第11张
'''
    带参数的装饰器
'''
def outer(flag):
    def wrapper(func):
        def inner(*args,**kwargs):
            if flag:
                '''执行函数前的操作'''
                print('执行函数前的操作')
            res = func(*args,**kwargs)
            if flag:
                print('执行函数后要做的')
                '''执行函数后要做的'''
            return res
        return inner
    return wrapper
'''
    outer(flag)中参数为True的结果:
        执行函数前的操作
        原函数内容
        执行函数后要做的
    outer(flag)中参数为False的结果:
        原函数内容
'''
@outer(True)
def func():
    print('原函数内容')
func()
带参数的装饰器

  4、多个装饰器装饰一个函数

  wrapper1和wrapper2同时装饰func()时,根据@wrapper1和@wrapper2的位置决定先后顺序,离func()比较近的先执行

  例如下面代码,先执行@wrapper2,相当于把wrapper2()中的内容嵌套在wrapper1中()

Java转python第四天 随笔 第13张
'''
    多个装饰器
'''
def wrapper1(func):
    def inner1(*args,**kwargs):
        print('执行装饰器1中函数前的操作')
        res = func(*args,**kwargs)
        print('执行装饰器1中函数后要做的')
        return res
    return inner1
def wrapper2(func):
    def inner2(*args,**kwargs):
        print('执行装饰器2中函数前的操作')
        res = func(*args,**kwargs)
        print('执行装饰器2中函数后要做的')
        return res
    return inner2

'''
    先走@wrapper2,再走wrapper1
    相当于在调用func()方法上面执行:
        func = wrapper2(func)
        func = wrapper1(func)
    运行结果:
            执行装饰器1中函数前的操作
            执行装饰器2中函数前的操作
            原函数内容
            执行装饰器2中函数后要做的
            执行装饰器1中函数后要做的
'''
@wrapper1            #fun = wrapper1(inner2) = inner1
@wrapper2            #fun = wrapper2(func) = inner2
def func():
    print('原函数内容')
func()
多个装饰器装饰同一个函数
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄