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、有参装饰器解析

原文地址:https://www.cnblogs.com/jonathan1314/p/6391115.html