返回介绍

编写类装饰器

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

到目前为止,我们已经编写了函数装饰器来管理函数调用,但是,正如我们已经见到的,Python 2.6和Python 3.0扩展了装饰器使其也能在类上有效。如同前面所提到的,尽管类似于函数装饰器的概念,但类装饰器应用于类——它们可以用于管理类自身,或者用来拦截实例创建调用以管理实例。和函数装饰器一样,类装饰器其实只是可选的语法糖,尽管很多人相信,它们使得程序员的意图更为明显并且能使不正确的调用最小化。

单体类

由于类装饰器可以拦截实例创建调用,所以它们可以用来管理一个类的所有实例,或者扩展这些实例的接口。为了说明这点,这里的第一个类装饰器示例做了前面一项工作——管理一个类的所有实例。这段代码实现了传统的单体编码模式,其中最多只有一个类的一个实例存在。其单体函数为管理的属性定义并返回一个函数,并且@语法自动在这个函数中包装了一个主体类:

为了使用它,装饰用来强化单体模型的类:

现在,当Person或Spam类稍后用来创建一个实例的时候,装饰器提供的包装逻辑层把实例构建调用指向了onCall,它反过来调用getInstance,以针对每个类管理并分享一个单个实例,而不管进行了多少次构建调用。这段代码的输出如下:

有趣的是,这里如果能像前面介绍的那样,使用nonlocal语句(在Python 3.0及其以后版本中可用)来改变封闭的作用域名称,我们在这里可以编写一个更为自包含的解决方案——后面的替代方案实现了同样的效果,它为每个类使用了一个封闭作用域,而不是为每个类使用一个全局表入口:

这个版本同样地工作,但是,它不依赖于装饰器之外的全局作用域中的名称。在Python 2.6或Python 3.0版本中,我们也可以用类编写一个自包含的解决方案——如下代码对每个类使用一个实例,而不是使用一个封闭作用域或全局表,并且它和其他的两个版本一样地工作(实际上,依赖于我们随后会见到的同样的编码模式是一个公用的装饰器类错误,这里我们只想要一个实例,但并不总是这样的情况):

要让这个装饰器成为一个完全通用的工具,可将其存储在一个可导入的模块文件中,在一个__name__检查下缩进self测试代码,并且在构建调用中使用**kargs语法支持关键字参数(我们将在建议的练习中讨论它)。

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

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

发布评论

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