• Python菜鸟之路:Python基础-逼格提升利器:装饰器Decorator


    一、装饰器

      装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。

      装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

      装饰器功能: 1. 自动执行装饰器函数 并且将被装饰函数当做参数对象本身,传递进去
             2. 将装饰器函数的返回值,重新赋值给被装饰的函数

    用伪代码就是如下表示:

    # 装饰器是一个函数,而其参数为另外一个函数
    def my_shiny_new_decorator(a_function_to_decorate) :
     
        # 在内部定义了另外一个函数:一个封装器。
        # 这个函数将原始函数进行封装,所以你可以在它之前或者之后执行一些代码
        def the_wrapper_around_the_original_function() :
     
            # 放一些你希望在真正函数执行前的一些代码
            print "Before the function runs"
     
            # 执行原始函数
            a_function_to_decorate()
     
            # 放一些你希望在原始函数执行后的一些代码
            print "After the function runs"
     
        #在此刻,"a_function_to_decrorate"还没有被执行,我们返回了创建的封装函数
        #封装器包含了函数以及其前后执行的代码,其已经准备完毕
        return the_wrapper_around_the_original_function
    
    def a_stand_alone_function() :
        print "I am a stand alone function, don't you dare modify me"
    
    # 好了,你可以封装它实现行为的扩展。可以简单的把它丢给装饰器
    # 装饰器本质:动态地把它和你要的代码封装起来,并且返回一个新的可用的函数。
    a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
    a_stand_alone_function_decorated()
    #输出 :
    #Before the function runs
    #I am a stand alone function, don't you dare modify me
    #After the function runs

    二、案例

    2.1 案例1.被装饰函数无参数的装饰器

     1 def outer(func):
     2     def inner():
     3         return func()
     4     return inner
     5 
     6 def outer(func):
     7     def inner():
     8         print("Start")
     9         ret = func()
    10         print("End")
    11         return ret
    12     return inner
    13 
    14 @outer
    15 def f1():
    16     print("f1")
    17 
    18 f1()
    19 
    20 out: 
    21 Start
    22 f1
    23 End

    从上边的案例可以看出,装饰器的本质是:自动执行装饰器函数,并且将被装饰函数当做参数对象本身,传递进去,等同于如下代码

     1 def f1():
     2     print("123")
     3 def outer(xxx):
     4     print('start')
     5     xxx()
     6     print('end')
     7 
     8 outer(f1)
     9 
    10 out:
    11 start
    12 123
    13 end

    -------等同于

     1 def outer(func):
     2     return "111"
     3 @outer
     4 def f1():
     5     print("f1")
     6 
     7 print(f1)
     8 
     9 out: 111
    10 # 将outer函数的return值,赋值给函数f1,这里很直白的体现了出来
     1 def outer(func):
     2     def inner():
     3         print("before")
     4         func()
     5         print("End")
     6     return inner()
     7 #在inner中,return inner() 这样会让inner直接执行,返回值就变成了None
     8 
     9 @outer
    10 def f1():
    11     print(123)
    12 
    13 print(f1)
    14 
    15 out: 
    16 before
    17 123
    18 End
    19 None
     1 def outer(func):
     2     def inner():
     3         print("before")
     4         r = func()
     5         print("End")
     6         return r
     7     return inner
     8 @outer
     9 def f1():
    10     print(123)
    11     return "函数的返回值"
    12 print("返回值:" ,f1())
    13 
    14 out: 
    15 before
    16 123
    17 End
    18 返回值: 函数的返回值

    2.2 案例2.被装饰函数有参数的装饰器

     1 def outer(func):
     2     def inner(arg):
     3         print("before")
     4         r = func(arg)
     5         print("End")
     6         return r
     7     return inner
     8 @outer
     9 def f1(arg):
    10     print(arg)
    11     return "单参数装饰器返回值"
    12 print("返回值:" ,f1('xxoo'))
    13 
    14 out: 
    15 before
    16 xxoo
    17 End
    18 返回值: 单参数装饰器返回值

    2.3 被装饰参数有多个参数装饰器

     1 def outer(func):
     2     def inner(*args, **kwargs):
     3         print("before")
     4         r = func(*args, **kwargs)
     5         print("End")
     6         return r
     7     return inner
     8 @outer
     9 def f1(arg1, arg2):
    10     print(arg1, arg2)
    11     return "多参数装饰器返回值"
    12 print("返回值:" ,f1('xxoo', '你大爷'))
    13 
    14 out:
    15 before
    16 xxoo 你大爷
    17 End
    18 返回值: 多参数装饰器返回值

    2.4 多个装饰器装饰函数

      多个装饰器装饰的话,本质和一个装饰器是一样的,记住要领:解析顺序是自下而上,执行顺序是自上而下

    2.5 带参数的装饰器函数 

     1 def Before(request,kargs):
     2     print('before')
     3 
     4 def After(request,kargs):
     5     print('after')
     6 
     7 
     8 def Filter(before_func,after_func):
     9     def outer(main_func):
    10         def wrapper(request,kargs):
    11 
    12             before_result = before_func(request,kargs)
    13             if(before_result != None):
    14                 return before_result;
    15 
    16             main_result = main_func(request,kargs)
    17             if(main_result != None):
    18                 return main_result;
    19 
    20             after_result = after_func(request,kargs)
    21             if(after_result != None):
    22                 return after_result;
    23 
    24         return wrapper
    25     return outer
    26 
    27 @Filter(Before, After)
    28 def Index(request,kargs):
    29     print('index')
    30 
    31 a = Index('1','2')
    32 print(a)
    33 
    34 out: 
    35 before
    36 index
    37 after
    38 None

     三、python内置装饰器函数  

      python还有几个内置装饰器函数分别是staticmethod、classmethod和property,作用分别是把类中定义的实例方法变成静态方法、类方法和类属性。

  • 相关阅读:
    常用词汇短语
    Java中的数据结构
    Java中的设计模式
    .NET中的编译、程序调用
    常用口语
    0. Angular框架原理
    茶叶
    NPOI自定义单元格背景颜色
    ASP.NET MVC添加Action就找不到
    navicat for mysql 导入SQL Server显示中文乱码解决办法
  • 原文地址:https://www.cnblogs.com/jishuweiwang/p/5553342.html
Copyright © 2020-2023  润新知