标签:python python3 装饰器 包装器 语法糖 详解 元函数 类装饰器
------------ 装饰器 -----------------------------------------------------
什么是装饰器
装饰器是为函数和类指定管理代码的一种方式。装饰器本身的形式是处理其他的可调用对象的可调用对象(如函数)。正如我们在本书前面所见到过的,Python装饰器以两种相关形式呈现:
函数装饰器在函数定义的时候进行名称重绑定,提供一个逻辑层来管理函数和方法或随后对它们调用。
类装饰器在类定义的时候进行名称重绑定,提供给一个逻辑层来管理类,或管理随后调用它们说创建的实例。
简而言之,装饰器提供了一种方法,在函数和类定义语句的末尾插入自动运行代码——对于函数装饰器,在def的末尾;对于类装饰器,在class的末尾。这样的代码可以扮演不同的角色,参见后面小节介绍。
管理调用和实例
例如,通常的用法中,这种自动运行的代码可能用来增强对函数和类的调用,它通过针对随后的调用安装包装器对象来实现这一点:
函数装饰器安装包装器对象,以在需要的时候拦截随后的函数调用并处理它们。
类装饰器安装包装器对象,以在需要的时候拦截随后的实例创建调用并处理它们。
装饰器通过自动把函数和类名重绑定到其他的可调用对象来实现这些效果,在def和class语句的末尾做到这点。当随后调用的时候,这些可调用对象可以自行诸如对函数调用跟踪和计时、管理对类实例属性的访问等任务。
管理函数和类
尽管本篇大多数实例都是用包装器来拦截随后对函数和类的调用,但这并非是使用装饰器的唯一方法:
函数装饰器也可以用来管理函数对象,而不是随后对它们的调用——例如,把一个函数注册到一个API。然而,我们在这里主要关注更为常见的用法,即调用包装器应用程序。
类装饰器也可以用来直接管理类对象,而不是实例创建调用——例如。用新的方法扩展类。因为这些用法和元类有很大的重合(实际上,都是在类创建过程的最后运行),我们将在随后看到更多的例子。
换句话说,函数装饰器可以用来管理函数调用和函数对象,类装饰器可以用来管理类实例和类自身。通过返回装饰的对象自身而不是一个包装器,装饰器变成了针对函数和类的一种简单的后创建步骤。
不管扮演什么样的角色,装饰器都提供了一种方便而明确的方法,来编写在程序开发阶段和现实产品系统中都有用的工具。
使用和定义装饰器
根据你的工作形式,你可能成为装饰器的用户或提供者。正如我们所看到的,Python本身带有具有特定角色的内置装饰器……静态方法装饰器、属性装饰器以及更多。此外,很多流行的Python工具包括了执行管理数据库或用户接口逻辑等任务的装饰器。在这样的情况中,我们不需要知道装饰器如何编码就可以完成任务。
对于更为通用的任务,程序员可以编写自己的任意装饰器。例如,函数装饰器可能通过添加跟踪调用、在调试时执行参数验证测试、自动获取和释放线程锁、统计调用函数的次数以进行优化等的代码来扩展函数。你可以想象添加到函数调用中的任何行为,都可以作为定制函数装饰器的备选。
另外一方面,函数装饰器设计用来只增强一个特定函数或方法调用,而不是一个完整的对象接口。类装饰器更好地充当后一种角色——因为它们可以拦截实例创建调用,它们可以用来实现任意的对象接口扩展或管理任务。例如,定制的类装饰器可以跟踪或验证对一个对象的每个属性引用。它们也可以用来实现代理对象、单体类 以及其他常用的变成模式。 实际上,我们将会发现很多类装饰器与前面见到的委托编程模式有很大的相似之处。
为什么使用装饰器
像狠毒欧高级Python工具一样,从纯技术的视角来看,并不是严格需要装饰器:它们的功能往往可以使用简单的辅助函数调用或其他的技术来实现(并且从基本的层面触发,我们总是可以手动地编写装饰器说自动执行的名称重绑定)。
也就是说,装饰器为这样的任务提供了一种显式的方法,它使得意图明确,可以最小化扩展代码的冗余,并且有助于确保正确的API使用:
装饰器有一种非常明确的语法,这使得它们比那些可能任意地远离主体函数或类的辅助函数调用更容易为人们发现。
当主体函数或类定义的时候,装饰器应用一次;在对类或函数的每次调用的时候,不必添加额外的代码(在未来可能必须改变)。
由于前面两点,装饰器使得一个API的用户不太可能忘记根据API需求扩展一个函数或类。
换句话说,除了其技术模型之外,装饰器提供了一些和代码维护性和审美相关的优点。此外,作为结构化工具,装饰器自然地促进了代码的封装,这减少了冗余性并使得未来变得更容易。
装饰器确实也有一些潜在的缺点……当它们插入包装类的逻辑,它们可以修改装饰的对象的类型,并且它们可能引发额外的调用。 另外一方面,同样的考虑也适用于任何为对象包装逻辑的技术。
我们将在本篇随后的真实代码中说明这些权衡。 尽管选择使用装饰器仍然多少有些主观性,但它们的优点引人注目,足以使其快速成为Python世界中的最佳时间。为了帮助你做出决定,让我们来看一些细节。
基础知识
让我们首先从一个符号的角度来第一次看一看装饰行为。我们很快将编写真正的代码,但是,由于装饰器的很多神奇之处可归结为自动重绑定操作,所以首先理解这一映射是很重要的。
函数装饰器
函数装饰器已经从Python 2.5开始可用。正如我们在本书前面所听见到的,它们主要只是一种语法糖:通过在一个函数的def语句的末尾来运行另一个函数,把最初的函数名重新绑定到新结果。
用法
函数装饰器是一个红源于函数的运行时声明,函数的定义需要遵守此声明。装饰器在紧挨着定义一个函数或方法的def语句之前的一行编写,并且它由@符号以及紧随其后的对于元函数的一个引用组成……这是惯例另一个函数的一个函数(或其他的可调用对象)。
在编码方面,函数装饰器自动将如下的语法
@decorator def F(arg): ... F(99)
映射为这一对等的形式,其中装饰器是一个单参数的可调用对象,它返回与F具有相同数目的参数的一个可调用对象:
本文出自 “Professor哥” 博客,谢绝转载!
标签:python python3 装饰器 包装器 语法糖 详解 元函数 类装饰器
原文地址:http://professor.blog.51cto.com/996189/1745316