返回介绍

编写函数装饰器

发布于 2024-01-29 22:24:14 字数 1124 浏览 0 评论 0 收藏 0

现回到代码层面。在本章剩下的内容里,我们将学习实际的例子来展示刚刚介绍的装饰器概念。本小节展示几个函数装饰器的实际例子,下一小节展示实际的类装饰器例子。此后,我们将通过使用类和函数装饰器的一些较大的例子来结束本章。

跟踪调用

首先,让我们回顾一下第31章介绍的跟踪器的例子。如下的代码定义并应用一个函数装饰器,来统计对装饰的函数的调用次数,并且针对每一次调用打印跟踪信息:

注意,用这个类装饰的每个函数将如何创建一个新的实例,带有自己保存的函数对象和调用计数器。还要注意观察,*args参数语法如何用来打包和解包任意的多个传入参数。这一通用性使得这个装饰器可以用来包装带有任意多个参数的任何函数(这个版本还不能在类方法上工作,但是,我们将在本小节稍后修改这一点)。

现在,如果导入这个模块的函数并交互地测试它,将会得到如下的一种行为——每次调用都初始地产生一条跟踪信息,因为装饰器类拦截了调用。这段代码在Python 2.6和Python 3.0下都能运行,就像本章中所有其他的代码一样,除非特别提示:

运行的时候,tracer类和装饰的函数分开保存,并且拦截对装饰的函数随后的调用,以便添加一个逻辑层来统计和打印每次调用。注意,调用的总数如何作为装饰的函数的一个属性显示——装饰的时候,spam实际上是tracer类的一个实例(对于进行类型检查的程序,可能还会衍生一次查找,但是通常是有益的)。

对于函数调用,@装饰语法可能比修改每次调用来说明额外的逻辑层要更加方便,并且它避免了意外地直接调用最初的函数。考虑如下所示的非装饰器的对等代码:

这一替代方法可以用在任何函数上,且不需要特殊的@语法,但是和装饰器版本不同,它在代码中调用函数的每个地方需要额外的语法。此外,它的意图可能不够明显,并且它不能确保额外的层将会针对常规调用而调用。尽管装饰器不是必需的(我们总是可以手动地重新绑定名称),它们通常是最为方便的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文