python3 [装饰器] 总结

装饰器的作用

  1. 装饰器本质上是一个高级Python函数,通过给别的函数添加@标识的形式实现对函数的装饰

2.装饰器的功能:

  • 它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
  • 它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
  • 装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
def fn(f1): #python是解释性语言,当他解释道@fn时会执行此函数,执行到def事定义一个函数,并不执行他,最后执行return将创建的内层函数返回
    def fc():
        print("这里开始对f1函数权限进行验证")
        f1()
        print("f1函数已经处理完毕了")
    return fc

@fn  #这个@fn标识符效果等同于f1=fn(f1)。
def f1():
    print("这里f1函数的功能展示")
 
因为@fn的效果等同于f1=fn(f1),所以直接调用f1()相当于实现了fn(f1)(),进而达到原来的效果。可以在不修改源代码的情况下为代码添加功能。

f1() # 直接执行

结果如下:

这里开始对f1函数进行权限验证
这里f1函数的功能展示
f1函数已经处理完毕了

多层装饰器

# 定义函数:完成包裹数据
def makeBold(fn): 
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

# 定义函数:完成包裹数据
def makeItalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makeBold  # 外层装饰(执行的时候先执行外层)
@makeItalic  # 内层装饰(装饰的时候先装饰内层)
def test1():
    return "hello world"

print(test1())

运行结果:

<b><i>hello world</i></b>

总结要点:

  • python中装饰器是随着程序的加载运行而自动加载的,跟调不调用方法没有关系.所以只要是装饰器内部函数以外的部分都会自动加载执行,不用调用。

  • 所以当一个函数被多个装饰器装饰时,装饰器的加载顺序是从内到外的。其实很好理解:装饰器是给函数装饰的,所以要从靠近函数的装饰器开始从内往外加载。

  • 但是执行顺序是由上到下的,及先执行makeBold并且makeBold中的fn()指向makeItalic,然后makeItalic中的fn()指向test1()

被装饰的函数有参数

def timefun(func):
    def wrapped_func(*args, **kwargs):
        print("call")
        func(*args, **kwargs) # 此处也应该使用*args接收参数,如果使用args接收的话,收到是参数是一个元组不会拆包
    return wrapped_func

@timefun
def foo(a, b, c):
    print(a+b+c)

foo(3,5,7)

带参数的装饰器

def strongdeco(*args, **kwargs):
    def basedeco(func):
        def wrapper(*args, **kwargs): # 此时返回的内层函数既有数据也有功能
            if args[0] == 1:  # 取出参数(对装饰器参数的使用)
                print('当装饰器参数=1时,这句话是对的')
            if args[0] == 0:
                print('当装饰器参数=0时,这句话是错的')
            print('上有天堂')
            output = func(*args, **kwargs)  # 此处无论被装饰的函数有无返回值都接收一下
            print('下有苏杭')
            return output
        return wrapper
    return basedeco
     # 3层函数
 
@strongdeco(0)
def testfun(name):
    '''这是一个测试'''
    print(f'{name}说:我就是我,不一样的烟火')
    print(testfun.__doc__)
    
 
if __name__ == '__main__':
    testfun('IT')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值