python装饰器

python装饰器
    一。什么是装饰器?

 

                  1、对现有已经实现功能的代码进行扩展。

 

                  2、不用修改被撞时对象的源代码和调用方法

 

      装饰器本质上就是一个python函数,他可以让其函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。

      装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。

    二 装饰器的形成过程。
      现在我有一个需求,我想让你测试这个函数的执行时间,在不改变函数代码的情况下。
      import time

      def func1():
      print('in func1')

      def timer(func):
      def inner():
      start =time.time()
      print(time.time() - start)
      return inner

      func1 = timer(func1)
      func1()

    但是如果有多个函数,我都想让你测试他们的执行时间,你每次是不是都得func1 = timer(func1)?这样还是有点麻烦,因为这些函数的函数名可能是不相同,有func1,func2,graph,等等,所以更简单的方法,python给你提供了,那就是语法糖。

      装饰器-语法糖
      def timer(func):
      def inner():
      start =time.time()
      func()
      print(time.time() - start)
      return inner

      @timer # func1 = timer(func1)
      def func1():
      print('in func1')
      func1()
      输出:
      in func1
      0.0

    装饰器-带参数的装饰器

      def timer(func):
      def inner(a):
      start =time.time()
      func(a)
      print(time.time() - start)
      return inner

      @timer # func1 = timer(func1)
      def func1(a):
      print(a)
      func1(1)
      输出:
      1
      0.0

    装饰器---hold住所有参数的装饰器
      import time
      def timer(func):
      def inner(*args,**kwargs):
      start = time.time()
      re = func(*args,**kwargs)
      print(time.time() - start)
      return re
      return inner

      @timer #==> func1 = timer(func1)
      def func1(a,b):
      print('in func1')

      @timer #==> func2 = timer(func2)
      def func2(a):
      print('in func2 and get a:%s'%(a))
      return 'fun2 over'

      func1('aaaaaa','bbbbbb')
      print(func2('aaaaaa'))

     上面的装饰器已经非常完美了,但是有我们正常情况下查看函数信息的方法在此处都会失效:

      def index():
      '''这是一个主页信息'''
      print('from index')

      print(index.__doc__) #查看函数注释的方法
      print(index.__name__) #查看函数名的方法

      如何解决呢?

      from functools import wraps

      def deco(func):
      @wraps(func) #加在最内层函数正上方
      def wrapper(*args,**kwargs):
      return func(*args,**kwargs)
      return wrapper

      @deco
      def index():
      '''哈哈哈哈'''
      print('from index')

      print(index.__doc__)
      print(index.__name__)

    三,开放封闭原则:
        1.对扩展是开放的

          为什么要对扩展开放呢?

          我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

        2.对修改是封闭的

          为什么要对修改封闭呢?

          就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

        装饰器完美的遵循了这个开放封闭原则。

    四。装饰器的主要功能和固定结构

      def timer(func):
      def inner(*args,**kwargs):
      '''执行函数之前要做的'''
      re = func(*args,**kwargs)
      '''执行函数之后要做的'''
      return re
      return inner

      from functools import wraps

      def deco(func):
      @wraps(func) #加在最内层函数正上方
      def wrapper(*args,**kwargs):
      return func(*args,**kwargs)
      return wrapper

    五。带有参数额装饰器:

      假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?

      一个一个的取消掉? 没日没夜忙活3天。。。

      过两天你领导想通了,再让你加上。。。

      带有参数的装饰器:
      def outer(flag):
      def timer(func):
      def inner(*args,**kwargs):
      if flag:
      print('''执行函数之前要做的''')
      re = func(*args,**kwargs)
      if flag:
      print('''执行函数之后要做的''')
      return re
      return inner
      return timer

      @outer(False)
      def func():
      print(111)

      func()

posted @ 2018-04-17 16:25  zhangliang666  阅读(108)  评论(0编辑  收藏  举报