元类

面向对象程序设计中,元类英語:)是一种实例是的类。普通的类定义的是特定对象的行为,元类定义的则是特定的类及其对象的行为。

不是所有面向对象编程语言都支持元类。如果类是第一类对象就可以比较方便地实现,此时的元类就是一种用来构建类的对象。[1]

Python例子

Python中,内建的类type是元类[2][3][4]。考虑下面这个最简单的Python类:

class Car:
    def __init__(self, make: str, model: str, year: int, color: str) -> None:
        self.make = make
        self.model = model
        self.year = year
        self.color = color

    @property
    def description(self):
        """Return a description of this car."""
        return f"{self.color} {self.year} {self.make} {self.model}"

在运行时间,Car自身是type的实例。上述Car类的源代码,不包括Car对象的细节,如它们的字节为单位的大小,它们在内存中的二进制格局,它们是如何分配的,每次建立Car的时候自动调用__init__方法,诸如此类。这些细节开始起作用不只是在建立新Car对象的时候,而是还在每次访问Car的任何属性的时候。在没有元类的语言中,这些细节是在语言规定中定义的并且不能被覆写(override)。在Python中,原类type控制着Car行为的这些细节。它们可以通过使用不同的原类替代type而覆写。

上面的例子包含了一些冗余代码来处理四个属性makemodelyearcolor。有可能使用原类来消除一些冗余。在Python中,原类最容易定义为type的子类。

class AttributeInitType(type):
    def __call__(self, *args, **kwargs):
        """Create a new instance."""

        # 首先,以正常缺省方式建立这个对象。
        obj = type.__call__(self, *args)

        # 此外,在这个新对象上设置属性。
        for name, value in kwargs.items():
            setattr(obj, name, value)

        # 返回这个新对象。
        return obj

这个原类只覆写对象创建。类行为的所有其他方面仍由type处理。

现在可以重写这个类Car来使用这个原类。在Python 3中,这是通过向类定义提供“关键字参数”metaclass来完成的:

class Car(object, metaclass=AttributeInitType):
    @property
    def description(self):
        """Return a description of this car."""
        return " ".join(str(value) for value in self.__dict__.values())

结果的对象Car像平常那样实例化,但是可以包含任何数目的关键字参数:

new_car = Car(make='Toyota', model='Prius', year=2005, color='Green', engine='Hybrid')

在语言和工具中的支持

下面是支持元类的一些最显著的编程语言

资源描述框架(RDF)和统一建模语言(UML)二者都支持元类。

另见

引用

  1. Ira R. Forman and Scott Danforth. . 1999. ISBN 0-201-43305-2 (英语).
  2. IBM Metaclass programming in Python, parts 1 页面存档备份,存于, 2 页面存档备份,存于 and 3 页面存档备份,存于
  3. Artima Forum: Metaclasses in Python 3.0 (part 1 of 2) 页面存档备份,存于 (part 2 of 2) 页面存档备份,存于
  4. David Mertz. . ONLamp. [June 28, 2006]. (原始内容存档于2003-04-30).
  5. Herb Sutter. (PDF). [2020-09-25]. (原始内容存档 (PDF)于2020-11-11).
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.