首页 > 文章列表 > Python装饰器:了解闭包与函数装饰器

Python装饰器:了解闭包与函数装饰器

Python 函数 装饰器
233 2023-04-21

一、闭包

在学习装饰器前,需要先了解闭包的概念。形成闭包的要点:

  • 函数嵌套
  • 将内部函数作为外部函数的返回值
  • 内部函数必须要使用到外部函数的变量

下面以一个计算列表平均值的案例来讲解闭包:

二、装饰器1.装饰器引入例如,有以下两个函数,分别计算两个数的和以及成绩:def new_add(a, b):
print("开始计算...")
r = add(a, b)
print("计算结束...")
return r


print(new_add(22, 33))

执行结果如下:

Python装饰器:了解闭包与函数装饰器

这种新创建一个函数的方式虽然没有修改原函数,但面临一个很严重的问题:

只能扩展指定函数,不能通用于其它函数,例如扩展上述的add函数,而不能扩展mul函数,如果想要扩展mul函数,只能再创建一个扩展函数;

因为,我们希望可以定义一个通用的扩展函数,可以作用域所有函数。这类不改变原函数代码的通用函数就是:装饰器。

2.函数装饰器

装饰器本质上是一个python函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,也就是为已经存在的对象添加额外功能,装饰器的返回值也是一个函数/类对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

1)被装饰函数不带参数

例如:

def introduce3(name, age, city):
print(f"我叫{name}, 我今年{age}岁了, 我来自{city}")

运行结果如下:

Python装饰器:了解闭包与函数装饰器

3)装饰器带参数

上述提到的是装饰器,一种是应用于被装饰的函数不带参数,一种是被装饰的函数带参数,那装饰器本身能否带参数呢?比如我定义一个变量,想通过传入不同的值来控制这个装饰器实现不同的功能。答案是肯定的,例如:

@wrapper_info
def introduce3(name, age, city):
print(f"我叫{name}, 我今年{age}岁了, 我来自{city}")

introduce3('刘德华', 28, '香港')

如果是装饰器函数带参数,例如上述的use_log,则需要在装饰器中传入参数:

@use_log('info')
def introduce4(name, age, city):
print(f"我叫{name}, 我今年{age}岁了, 我来自{city}")

小结

什么是装饰器?

在不改变原函数代码的情况下,给原函数增加了一些额外的功能,并且能够通用于其他函数,这样的函数就称作为装饰器。

装饰器的调用

可以通过传统调用函数的方式进行调用,也可以通过@装饰器的方式调用

装饰器的特点

  • 通过装饰器,可以在不修改原来函数的情况下对函数进行扩展
  • 一个函数可以同时指定多个装饰器