【python进阶 笔记】装饰器(decorator) (重点)

【python进阶 笔记】装饰器 (重点)

目录

1. 装饰器介绍

1.1. 引入代码

1.2. 需求来了(通过需求逐步了解)

1.3. 装饰器的实现过程(重要)

2. 装饰器(decorator)作用

3. 装饰器示例

3.1. 对无返回值、无参数函数的装饰

3.2. 对有参数、无返回值的函数进行装饰

3.3. 用同一个装饰器对多个函数进行装饰

3.4. 装饰器几时开始装饰?!

3.5. 对不定长参数的函数进行装饰!

3.6. 对有返回值的不定长参数函数进行装饰(重要)

4. 多个装饰器对同一个函数装饰

多个装饰器对同一个函数装饰 应用Demo

5. 装饰器带参数,在原有装饰器的基础上,设置外部变量

6. 类装饰器(了解)


1. 装饰器介绍

装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,这也是Python面试必备的问题。

1.1. 引入代码

#### 第一段 ####
def foo():
    print('foo')

foo  # 表示是函数,变量名指向了函数
foo()  # 表示执行foo函数

#### 第二段 ####
def foo():
    print('foo')

foo = lambda x: x + 1  # lambda 匿名函数,默认返回值是表达式的结果

foo()  # 执行lambda表达式,而不再是原来的foo函数,因为foo这个名字被重新指向了另外一个匿名函数

在python中,所有的方法名、函数名、变量名和类的名字通常是不允许相同的,python中都把他们当作一个变量名来对待。

故上面的代码中,函数名仅仅是个变量,只不过指向了定义的函数而已,所以才能通过 函数名()调用。如果 函数名=xxx被修改了,那么当在执行 函数名()时,调用的就不是之前的那个函数了

 

1.2. 需求来了(通过需求逐步了解)

初创公司有N个业务部门,基础平台部门负责提供底层的功能,如:数据库操作、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()

目前公司有条不紊的进行着,但是,以前基础平台的开发人员在写代码时候没有关注验证相关的问题,即:基础平台的提供的功能可以被任何人使用。现在需要对基础平台的所有功能进行重构,为平台提供的所有功能添加验证机制,即:执行功能前,先进行验证。

 

(方案1)老大把工作交给 Low B,他是这么做的:

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

当天Low B 被开除了…

 

(方案2:对相关功能的函数进行一一修改老大把工作交给 Low BB,他是这么做的:

############### 基础平台提供的功能如下 ############### 

def f1():
    # 验证1
    # 验证2
    # 验证3
    print('f1')

def f2():
    # 验证1
    # 验证2
    # 验证3
    print('f2')

def f3():
    # 验证1
    # 验证2
    # 验证3
    print('f3')

def f4():
    # 验证1
    # 验证2
    # 验证3
    print('f4')

############### 业务部门不变 ############### 
### 业务部门A 调用基础平台提供的功能### 

f1()
f2()
f3()
f4()

### 业务部门B 调用基础平台提供的功能 ### 

f1()
f2()
f3()
f4()

代码重用性太大不行)过了一周 Low BB 被开除了…

 

方案3:定义一个函数用来调用)老大把工作交给 Low BBB,他是这么做的:

只对基础平台的代码进行重构,其他业务部门无需做任何修改

############### 基础平台提供的功能如下 ############### 

def check_login():
    # 验证1
    # 验证2
    # 验证3
    pass


def f1():

    check_login()

    print('f1')

def f2():

    check_login()

    print('f2')

def f3():

    check_login()

    print('f3')

def f4():

    check_login()

    print('f4')

老大看了下Low BBB 的实现,嘴角漏出了一丝的欣慰的笑,语重心长的跟Low BBB聊了个天:

老大说:

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

  • 封闭:已实现的功能代码块,不能再进行修改
  • 开放:对扩展开发

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

方案4:用装饰器)

def w1(func):
    def inner():
        # 验证1
        # 验证2
        # 验证3
        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 之前都进行【验证】操作,并且其他业务部门无需做任何操作。

 

这段代码的内部执行原理

以下方代码为例:

def set_func(func):
	def call_func():
		print("---这是权限验证1----"
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值