什么是闭包
在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。
闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。
在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
产生闭包
- 必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套。
- 内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量。
- 外部函数必须返回内嵌函数——必须返回那个内部函数。
闭包的概念很简单:一个可以引用在函数闭合范围内变量的函数。即"内部函数"
,只有那个内部函数才有所谓的__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:把类中定义的实例方法变成类属性。
为什么使用装饰器
- 模块化且清晰明确
- 代码重用
- 装饰器是显式的,增强可读性
如何使用装饰器
Python标准库中包括很多包含装饰器的模块,并且很多常用工具和框架利用它们实现常功能。例如:
- 要使用一个类上的方法不需要这个类的实例(@classmethod或@staticmethod)
- mock模块(单元测试python3.3后加入标准库-@mock.patch或@mock.patch.object)
- Django(@login_required, @permission_reqired)
- Flask(@app.route) 充当url与函数之间的注册表
- Celery(@task) 返回Task类实例
- 插入日志、性能测试、事务处理、缓存、权限校验等场景
- 记录结果、增加计时逻辑来检测性能等