返回介绍

21.8 本章小结

发布于 2024-02-05 21:59:46 字数 1292 浏览 0 评论 0 收藏 0

类元编程是指动态创建或定制类。在 Python 中,类是一等对象,因此本章首先说明如何通过调用内置的 type 元类,使用函数创建类。

接下来的一节继续讨论第 20 章使用描述符实现的 LineItem 类,解决一个遗留问题:如何让生成的储存属性名中包含托管属性的名称(例如,把 _Quantity#1 变成 _Quantity#price)。解决办法是使用类装饰器。说到底,类装饰器是函数,其参数是被装饰的类,用于审查和修改刚创建的类,甚至替换成其他类。

然后,本章讨论了模块中不同部分的代码何时运行。我们发现,所谓的“导入时”和“运行时”之间有重叠,不过很明显,import 语句会触发运行大量代码。知道代码何时运行至关重要,可是有些规则难以捉摸,因此我们通过两个计算时间练习对此做了说明。

接下来,本章介绍了元类。我们得知,所有类都直接或间接地是 type 的实例,因此在 Python 中,type 是“根元类”。然后,我们对之前的计算时间练习做了修改,以此说明元类可以定制类的层次结构。类装饰器则不同,它只能影响一个类,而且对后代可能没有影响。

随后,我们实际使用元类,解决 LineItem 类中储存属性的命名问题。最终写出的代码比类装饰器难懂一些,不过可以封装在一个模块里,这样用户只需继承看似普通的一个类(model.Entity),而不用知道它是元类(model.EntityMeta)的实例。这种处理方式让人想起了 Django 和 SQLAlchemy 的 ORM API:使用元类实现,用户却根本无需知道。

我们实现的第二个元类为 model.EntityMeta 类添加了一个小功能:定义 __prepare__ 方法,返回一个 OrderedDict 对象,用于储存名称到属性的映射。这样做能保留要构建的类在定义体中绑定属性的顺序,提供给元类的 __new__ 和 __init__ 等方法使用。在这个示例中,我们定义了类属性 _field_names,因此用户可以使用 Entity.field_names() 方法以 Validated 描述符出现在源码中的顺序获取描述符。

最后一节,我们概述了 Python 为所有类提供的属性和方法。

元类是充满挑战、让人兴奋的功能,有时会被故作聪明的程序员滥用。最后,我们回顾一下 Alex Martelli 在他写的“水禽和抽象基类”一文的最后给我们的建议:

此外,不要在生产代码中定义抽象基类(或元类)……如果你很想这样做,我打赌可能是因为你想“找茬”,刚拿到新工具的人都有大干一场的冲动。如果你能避开这些深奥的概念,你(以及未来的代码维护者)的生活将更愉快,因为代码简洁明了。

——Alex Martelli

说出上述至理名言的人不仅是 Python 元编程大师,还是造诣颇深的软件工程师,负责世界上几个最重要的 Python 应用。

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

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

发布评论

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