返回介绍

元类与类装饰器的关系:第二回合

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

如果本章中的示例还没有让你大脑爆炸,请记住,上一章的类装饰器常常和本章的元类在功能上有重合。这源自于如下的事实:

·在class语句的末尾,类装饰器把类名重新绑定到一个函数的结果。

·元类通过在一条class语句的末尾把类对象创建过程路由到一个对象来工作。

尽管这些是略有不同的模型,实际上,它们通常可实现同样的目标,虽然采用的方式不同。实际上,类装饰器可以用来管理一个类的实例以及类自身。尽管装饰器可以自然地管理类,然而,用元类管理实例有些不那么直接。元类可能最好用于类对象管理。

基于装饰器的扩展

例如,前面小节的元类示例,像创建的一个类添加方法,也可以用一个类装饰器来编写。在这种模式下,装饰器大致与元类的__init__方法对应,因为在调用装饰器的时候,类对象已经创建了。也与元类类似,最初的类类型是保留的,因为没有插入包装器对象层。如下的输出与前面的元类代码的输出相同:

换句话说,至少在某些情况下,装饰器可以像元类一样容易地管理类。反过来就不那么直接了,元类可以用来管理实例,但是只有有限的力量。下一小节将说明这点。

管理实例而不是类

正如我们已经见到的,类装饰器常常可以和元类一样充当类管理角色。元类往往和装饰器一样充当实例管理的角色,但是,这更复杂一点。即:

·类装饰器可以管理类和实例。

·元类可以管理类和实例,但是管理实例需要一些额外工作。

也就是说,某些应用可能用一种方法或另一种方法编写更好。例如,前一章中的类装饰器示例,无论何时,获取一个类实例的任意常规命名的属性的时候,它用来打印一条跟踪消息:

这段代码运行的时候,装饰器使用类名重新绑定来把实例对象包装到一个对象中,该对象在如下的输出中给出跟踪行:

尽管用一个元类也可能实现同样的效果,但它似乎概念上不太直接明了。元类明确地设计来管理类对象创建,并且它们有一个为此目的而设计的接口。要使用元类来管理实例,我们必须依赖一些额外力量。如下的元类和前面的装饰器具有同样的效果和输出:

这也有效,但是它依赖于两个技巧。首先,它必须使用一个简单的函数而不是一个类,因为type子类必须附加给对象创建协议。其次,必须通过手动调用type来手动创建主体类;它需要返回一个实例包装器,但是元类也负责创建和返回主体类。其实,在这个例子中,我们将使用元类协议来模仿装饰器,而不是按照相反的做法。由于它们都在一条class语句的末尾运行,所以在很多用途中,它们都是同一方法的变体。元类版本运行的时候,产生与装饰器版本同样的输出:

你应该自己研究这两个示例版本,以权衡其利弊。通常,元类可能更适合于类管理,因为它们就设计为如此。类装饰器可以管理实例或类,然而,它们不是更高级元类用途的最佳选择(我们没有足够篇幅在本书中介绍,如果你在阅读完本章后,还想学习关于装饰器和元类的更多内容,请在Web上搜索或参阅Python标准手册的内容)。下一小节用一个更为常见的例子来结束本章,自动对一个类的方法应用操作。

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

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

发布评论

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