• Python自动化开发


    本节内容

    一、装饰器导引

      1、函数对象特性

      2、扩展业务功能需求

      3、各种解决方案

    二、装饰器解析

      1、装饰器基本概念

      2、无参装饰器解析

     

    一、装饰器导引

    1、函数对象特性

    #### 第一波 ####
    def foo():        # 表示定义函数
        print('foo')  # 表示函数体
     
    foo     #表示是函数名,指向函数体的地址
    foo()   #表示执行foo函数
     
    #### 第二波 ####
    def foo():
        print('foo')
     
    foo = lambda x: x + 1
     
    foo()   # 执行下面的lambda表达式,而不再是原来的foo函数,因为函数 foo 被重新定义了
    
    #### 第三波 ####
    def now():
        print('2017-01-12')
    
    f = now
    f()  # 执行结果 2017-02-12
    
    # 函数也是一个对象,而且函数对象也可以被赋值给变量,所以通过该变量也能调用该函数
    

      

    2、扩展业功能需求

    初创公司有N个业务部门,1个基础平台部门,基础平台负责提供底层的功能,如:数据库操作、redis调用、监控API等功能。

    业务部门使用基础功能时,只需调用基础平台提供的功能即可。如下:

    ############### 基础平台提供的功能如下 ###############
     
    def f1():
        print('f1')
     
    def f2():
        print('f2')
     
    def f3():
        print('f3')
     
    def f4():
        print('f4')
     
    ############### 业务部门A 调用基础平台提供的功能 ###############
     
    f1()
    f2()
    f3()
    f4()
     
    ############### 业务部门B 调用基础平台提供的功能 ###############
     
    f1()
    f2()
    f3()
    f4()
    

     

    目前公司有条不紊的进行着,但是,以前基础平台的开发人员在写代码时候没有关注验证相关的问题,即:基础平台的提供的功能可以被任何人使用。

    现在需要对基础平台的所有功能进行重构,为平台提供的所有功能添加验证机制,即:执行功能前,先进行验证。

    3、各种解决方案

    员工一,他是这么做的:

    跟每个业务部门交涉,每个业务部门自己写代码,调用基础平台的功能之前先验证。诶,这样一来基础平台就不需要做任何修改了。
    

    当天他被开除了。

    员工二,他是这么做的:

    只对基础平台的代码进行重构,让N业务部门无需做任何修改
     1 ############### 基础平台提供的功能如下 ############### 
     2 
     3 def f1():
     4     # 验证1
     5     # 验证2
     6     # 验证3
     7     print('f1')
     8 
     9 def f2():
    10     # 验证1
    11     # 验证2
    12     # 验证3
    13     print('f2')
    14 
    15 def f3():
    16     # 验证1
    17     # 验证2
    18     # 验证3
    19     print ('f3')
    20 
    21 def f4():
    22     # 验证1
    23     # 验证2
    24     # 验证3
    25     print ('f4')
    26 
    27 ############### 业务部门不变 ############### 
    28 ### 业务部门A 调用基础平台提供的功能### 
    29 
    30 f1()
    31 f2()
    32 f3()
    33 f4()
    34 
    35 ### 业务部门B 调用基础平台提供的功能 ### 
    36 
    37 f1()
    38 f2()
    39 f3()
    40 f4()
    View Code

    过了一周,他被开除了

    员工三,他是这么做的:

    只对基础平台的代码进行重构,其他业务部门无需做任何修改
    
     1 ############### 基础平台提供的功能如下 ############### 
     2 
     3 def check_login():
     4     # 验证1
     5     # 验证2
     6     # 验证3
     7     pass
     8 
     9 
    10 def f1():
    11     
    12     check_login()
    13 
    14     print('f1')
    15 
    16 def f2():
    17     
    18     check_login()
    19 
    20     print('f2')
    21 
    22 def f3():
    23     
    24     check_login()
    25 
    26     print('f3')
    27 
    28 def f4():
    29     
    30     check_login()
    31     
    32     print('f4')
    View Code

    战战兢兢,员工三保留了工作,进一步观察,哎工作不易啊

    最终大BOSS给了解答:

    写代码要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,

    但可以被扩展,即:

    • 封闭:已实现的功能代码块,不能被修改
    • 开放:扩展已实现的代码功能块

    如果将开放封闭原则应用到上述需求中,那么就不允许在函数f1、f2、f3、f4的内部进行修改代码,大BOSS给了如下一个实现方案

    def w1(func):
        def inner():
            # 验证1
            # 验证2
            # 验证3
            return func()
        return inner
     
    @w1
    def f1():
        print('f1')
    @w1
    def f2():
        print('f2')
    @w1
    def f3():
        print('f3')
    @w1
    def f4():
        print('f4)
    

      

    对于上述代码,也是仅仅对基础平台的代码进行修改,就可以实现在其他人调用函数f1、f2、f3、f4之前都进行【验证】,

    并且其他业务部门无需做任何的操作。内部的实现原理就是装饰器

    二、装饰器解析

    1、装饰器基本概念

    A 装饰器定义:本质是函数,功能是为其他函数添加新功能

    B 遵循原则:

      不修改被修饰函数的源代码

      为被装饰函数添加新功能后,不修改被修饰函数的调用方式

    C 分解装饰器:装饰器 = 高阶函数 + 函数嵌套 + 闭包

    其中一个函数参数为函数名,或者函数的返回值是一个函数名,这样的函数称之为高阶函数

    2、无参装饰器解析

    单独以f1为例:

    # 定义装饰器
    def w1(func):
        def inner():
            # 验证功能
            print('我是为函数 %s 添加的验证模块' % func.__name__)
            return func()
        return inner
    
    # @w1为Python的语法糖,下面一段代码本质执行f1 = w1(f1)
    @w1  
    def f1():  # 不修改被修饰函数的源代码
        print('调用f1功能')
    
    f1()       # 不修改被修饰函数的调用方式
    

    程序从上到下依次执行

    (一) def w1(func):   # 将函数w1加载到内存,未执行w1函数体

    (二) @w1               # @函数名,Python一种语法糖,等价于 f1 = w1(f1),其中参数f1被保存下来。所以@w1内部执行如下

      执行w1()函数体,参数为f1:

        def inner():  # 将函数inner加载到内存,未执行inner函数体

        return inner

    以上操作完成 函数f1 = w1(f1),无论原先函数f1,还是被重构inner()重构的函数f1,皆未被执行

    (三) f1()    # 执行函数被重构的f1()函数体,也就是执行函数 inner():

      print('我是为函数 %s 添加的验证模块' % func.__name__)

      return func():调用原函数 f1(),也就是 print('调用f1功能')

    3、有参装饰器解析

  • 相关阅读:
    SVN简介
    TFS简介
    UML简介
    C#++c1FlexGrid+帮助文档09
    vmware虚拟机 C硬盘空间 无损扩容 新测
    批处理命令中set定义的两种变量介绍 计算机基础知识
    ASP.NET获取网站根目录(路径)
    VMware(bridge、NAT、host-only、custom)含义
    spring3.0+Atomikos 构建jta的分布式事务
    在做了 BasePage 时: 只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态。还请确保在应用程序配置的 / / 节中包括
  • 原文地址:https://www.cnblogs.com/jonathan1314/p/6391115.html
Copyright © 2020-2023  润新知