Python函数式编程之装饰器

概念

      前面我们有了闭包函数的概念,我们再去理解装饰器会相对容易一些。python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针)。装饰器函数的外部函数传入我要装饰的函数名字,返回经过修饰后函数的名字;内层函数(闭包)负责修饰被修饰函数。从上面这段描述中我们需要记住装饰器的几点属性,以便后面能更好的理解:

    实质:是一个函数

   参数:是你要装饰的函数名(并非函数调用

   返回:是装饰完的函数名(也非函数调用

   作用:为已经存在的对象添加额外的功能

   特点:不需要对对象做任何的代码上的变动

python装饰器有很多经典的应用场景,比如:插入日志、性能测试、事务处理、权限校验等。装饰器是解决这类问题的绝佳设计。并且从引入中的列子中我们也可以归纳出:装饰器最大的作用就是对于我们已经写好的程序,我们可以抽离出一些雷同的代码组建多个特定功能的装饰器,这样我们就可以针对不同的需求去使用特定的装饰器,这时因为源码去除了大量泛化的内容而使得源码具有更加清晰的逻辑

函数装饰器

# -*- coding: utf-8 -*-##-------------------------------------------------------------------------------# ProjectName:     PythonTest1308# FileName:       DecoratorTest # Author:        MuTou# Date:         2019/9/15# Description:自定义装饰器#-------------------------------------------------------------------------------#有一台打印机,存在很多方法,打印、复印、彩印、扫描、传真等;在以上方法操作之前都必须先自检# (自检当前设备连接接口是否正常)#自定义一个装饰器def  selfCheck(func):    #需要实现额外扩展功能的函数    def function():        print("自检")        func()        print("自动断开连接")    #实际就调用第二层函数:必须返回的是函数的对象,不能够是函数的具体值,具体实现    return function#打印功能@selfCheckdef  printer():    print("打印功能")
printer()#复印功能@selfCheckdef  copy():    print("复印功能")copy()#彩印@selfCheckdef  colorPrint():    print("彩印功能 ")#扫描colorPrint()
#有一个需求:写过函数(九九乘法表、奇数偶数求和函数、求质数、斐波拉契....),在以上函数中还要完成#每个函数执行时间的统计#声明一个装饰器import timedef  timeDec(func):    def count_Time(number1,number2):        start_Time=time.time()        func(number1,number2)        end_Time=time.time()        print("运行时间:%s"%(end_Time-start_Time))    return count_Time@timeDecdef add(number1,number2):    print(number1+number2)
add(1,2)# def  language(*args):#     def  get(name):#         print(name)#         name("哈哈哈哈哈")#         for i in args:#             print(i)#     return getdef  language(type):    if type=="Chinese":       print("使用中文问候")    elif type=="English":        print("please use english wenhou")    elif type=="taiYu":        print("shua wo de  ka")    def execute_Method(methodName):        def func(name):            methodName(name)        return func    return execute_Method
#打招呼的def  chinese(name):    print("你好:%s"%name)
@language("English")def english(name):    print("Hello:%s"%name)#调用english("John")@language("Chinese")def taiYu(name):    print("萨瓦迪卡:%s"%name)taiYu("瓦提啦啦啦")def  janPan(name):    print("扣你起哇:%s"%name)
#使用装饰器,传入对应的语言(Chinese、Enligh、TaiYu、JanPan),并给出对应的语种问候语

类装饰器

       前面我们提到的都是让函数作为装饰器去装饰其他的函数或者方法,那么可不可以让 一个类发挥装饰器的作用呢?答案肯定是可以的,一切皆对象么,函数和类本质没有什么不一样。类的装饰器是什么样子的呢?​​​​​​​

# -*- coding: utf-8 -*-##-------------------------------------------------------------------------------# ProjectName:     PythonTest1308# FileName:       DecoratorTest # Author:        MuTou# Date:         2019/9/15# Description:自定义装饰器#-------------------------------------------------------------------------------class Decorator(object):    def __init__(self, f):        self.f = f    def __call__(self):        print("decorator start")        self.f()        print("decorator end")
@Decoratordef func():    print("func")
func()

      这里有注意的是:__call__()是一个特殊方法,它可将一个类实例变成一个可调用对象:​​​​​​​

p = Decorator(func) # p是类Decorator的一个实例p() # 实现了__call__()方法后,p可以被调用

      要使用类装饰器必须实现类中的__call__()方法,就相当于将实例变成了一个方法。

装饰器链

      一个python函数也可以被多个装饰器修饰,要是有多个装饰器时,这些装饰器的执行顺序是怎么样的呢?​​​​​​​

# -*- coding: utf-8 -*-##-------------------------------------------------------------------------------# ProjectName:     PythonTest1308# FileName:       DecoratorTest # Author:        MuTou# Date:         2019/9/15# Description:自定义装饰器#-------------------------------------------------------------------------------def  test_A(f):    return lambda :"打印A"+f()
def test_B(f):    return lambda :"打印B"+f()
@test_A @test_Bdef test_main():    return  "打印main"
print(test_main())#输出结果为:打印A打印B打印main

可见,多个装饰器的执行顺序:是从近到远依次执行。

需要了解更多可关注以下公众号,每日更新一篇测试文章

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zemuerqi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值