Python 闭包和装饰器

什么是闭包

在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。

闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。

在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。

产生闭包

  • 必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套。
  • 内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量。
  • 外部函数必须返回内嵌函数——必须返回那个内部函数。

闭包的概念很简单:一个可以引用在函数闭合范围内变量的函数。即"内部函数"
,只有那个内部函数才有所谓的__closure__属性。

什么是装饰器

装饰器是这样一种设计模式:如果一个类(函数)希望添加其他类(函数)的一些功能,而不希望
通过继承或是直接修改源代码实现,那么可以使用装饰器模式。

简单来说Python中的装饰器就是指某些函数或其他可调用对象,以函数或类作为可选输入参数,
然后返回函数或类的形式。通过这个在Python2.6版本中被新加入的特性可以用来实现装饰器设计
模式。

装饰器就是一个可以接受调用也可以返回调用的函数,该函数接受被装饰的函数作为其位置参数。
装饰器通过使用该参数来执行某些操作,然后返回原始参数或一些其他的调用。

函数也是对象,也可以当做参数传递。

装饰器应用

在装饰器中置入通用功能的代码来降低程序复杂度。例如

• 引入日志

• 增加计时逻辑来检测性能

• 给函数加入事务的能力

• 权限控制

应用多个装饰器

• 封装时,至下而上

• 执行时,至上而下

什么是元数据

元数据(Metadata),又称中介数据、中继数据,为描述数据的数据(data about data),主要是
描述数据属性(property)的信息。

函数的重要的元信息比如名字、文档字符串、注解和参数签名等。

装饰器后为什么元数据会丢失

因为return执行的,是经过调用封装后的函数。

利用@functools.wraps(fun),将一个函数的重要内容复制到另一个函数。

注意:定义装饰器时,应使用 functools 库中的 @wraps 装饰器来注解底层包装函数。

内置的装饰器

Python提供了类装饰器与@staticmethod,@classmethod,@property和这三个在面向对象编
程中常用的装饰器。

1、staticmethod:把类中定义的实例方法变成静态方法

2、classmethod:把类中定义的实例方法变成类方法

3、property:把类中定义的实例方法变成类属性。

为什么使用装饰器

  1. 模块化且清晰明确
  2. 代码重用
  3. 装饰器是显式的,增强可读性

如何使用装饰器

Python标准库中包括很多包含装饰器的模块,并且很多常用工具和框架利用它们实现常功能。例如:

  1. 要使用一个类上的方法不需要这个类的实例(@classmethod或@staticmethod)
  2. mock模块(单元测试python3.3后加入标准库-@mock.patch或@mock.patch.object)
  3. Django(@login_required, @permission_reqired)
  4. Flask(@app.route) 充当url与函数之间的注册表
  5. Celery(@task) 返回Task类实例
  6. 插入日志、性能测试、事务处理、缓存、权限校验等场景
  7. 记录结果、增加计时逻辑来检测性能等
闭包是一个函数对象,它引用了一些在其定义时外部环境的变量。在Python中,闭包常常用来创建装饰器装饰器其实就是一个闭包,它接受一个函数作为参数,并返回一个替代版函数。闭包允许我们在不修改原始函数的情况下,添加一些额外的功能或逻辑。 一个典型的装饰器的例子可以是这样的:在一个函数外面定义一个装饰器函数,然后通过在要装饰的函数之前添加@装饰器名称的语法糖,来应用装饰器闭包装饰器的实现机制是类似的,都是通过嵌套函数的方式来实现的。在闭包中,内部函数引用了外部函数的变量。而在装饰器中,装饰器函数接受一个函数作为参数,并返回一个内部函数,内部函数可以访问外部函数的变量。 在闭包装饰器的实现过程中,都需要注意作用域的规则。在闭包中,内部函数可以访问外部函数的局部变量,而在装饰器中,装饰器函数可以访问被装饰函数的变量。 闭包装饰器提供了一种灵活的方式来扩展函数的功能,使得我们可以在不修改原始函数的情况下,添加一些额外的逻辑。它们是Python中非常强大而且常用的特性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [python中的闭包装饰器解释](https://blog.csdn.net/qq_39567748/article/details/99596644)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [python高级之装饰器](https://blog.csdn.net/qq_35396496/article/details/109147229)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩未零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值