python装饰器原理与用法深入详解

  

本文实例讲述了python装饰器原理与用法。分享给大家供大家参考,具体如下:

  
  

你会Python嘛?
  我会!
  那你给我讲下Python装饰器吧!
  Python装饰器啊?我没用过哎

     

以上是我一个哥们面试时候发生的真实对白。

  

<强> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -分割线- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  

简言之,python装饰器就是用于<强>拓展原来函数功能的一种函数强劲,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
  一般而言,我们要想拓展原来函数代码,最直接的办法就是侵入代码里面修改,例如:

        导入的时间   def func ():   打印(“hello”)   time . sleep (1)   打印(“世界”)      之前      

这是我们最原始的的一个函数,然后我们试图记录下这个函数执行的总时间,那最简单的做法就是:

        #原始侵入,篡改原函数   导入的时间   def func ():   开始时间=time.time ()   打印(“hello”)   time . sleep (1)   打印(“世界”)   endTime=time.time ()   毫秒断开=(endTime -开始时间)* 1000   打印(“时间就是% d女士”%毫秒断开)      之前      

但是如果你的老板在公司里面和你说:“小祁,这段代码是我们公司的核心代码,你不能直接去改我们的核心代码。”那该怎么办呢,我们仿照装饰器先自己试着写一下:

        #避免直接侵入原函数修改,但是生效需要再次执行函数   导入的时间   def德科(函数):   开始时间=time.time ()   函数()   endTime=time.time ()   毫秒断开=(endTime -开始时间)* 1000   打印(“时间就是% d女士”%毫秒断开)   def func ():   打印(“hello”)   time . sleep (1)   打印(“世界”)   if __name__==癬_main__”:   f=函数   德科(f) #只有把func()或者f()作为参数执行,新加入功能才会生效   打印(“f。__name__”, f.__name__) # f的名字就是函数      之前      

这里我们定义了一个函数装饰,它的参数是一个函数,然后给这个函数嵌入了计时功能,然后你可以拍着胸脯对老板说,看吧,不用动你原来的代码,我照样拓展了它的函数功能。

  

然后你的老板有对你说:“小祁,我们公司核心代码区域有一千万个func()函数,从func01()到func1kw(),按你的方案,想要拓展这一千万个函数功能,就是要执行一千万次德科()函数,这可不行呀,我心疼我的机器。”

  

好了,你终于受够你老板了,准备辞职了,然后你无意间听到了装饰器这个神器,突然发现能满足你闫博士的要求了。

  

我们先实现一个最简陋的装饰器,不使用任何语法糖和高级语法,看看装饰器最原始的面貌:

        #既不需要侵入,也不需要函数重复执行   导入的时间   def德科(函数):   def包装():   开始时间=time.time ()   函数()   endTime=time.time ()   毫秒断开=(endTime -开始时间)* 1000   打印(“时间就是% d女士”%毫秒断开)   返回包装   @deco   def func ():   打印(“hello”)   time . sleep (1)   打印(“世界”)   if __name__==癬_main__”:   f f=func #这里被赋值为函数,执行f()就是执行func ()   f ()      之前      

这里的装饰函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。其中作为参数的这个函数func()就在返回函数包装()的内部执行。然后在函数func()前面加上@deco, func()函数就相当于被注入了计时功能,现在只要调用func(),它就已经变身为“新的功能更多”的函数了。

  

所以这里装饰器就像一个注入符号:有了它,拓展了原来函数的功能既不需要侵入函数内更改代码,也不需要重复执行原函数。

        #带有参数的装饰器   导入的时间   def德科(函数):   def包装器(a, b):   开始时间=time.time ()   func (a, b)   endTime=time.time ()   毫秒断开=(endTime -开始时间)* 1000   打印(“时间就是% d女士”%毫秒断开)   返回包装   @deco   def func (a, b):   打印(“你好,这里是添加func:”)   time . sleep (1)   打印(“结果是% d % (a + b))   if __name__==癬_main__”:   f=函数   f(3、4)   # func ()      

python装饰器原理与用法深入详解