元类

在面向对象程序设计中，元类（）是一种实例是类的类。普通的类定义的是特定对象的行为，元类定义的则是特定的类及其实例的行为。不是所有面向对象编程语言都支持元类。在它能做的事情之中，元类可以覆写任何给定方面类行为的程度是不同的。元类可以通过使类成为头等对象来实现，在这种情况下元类简单的就是构造类的一个对象。每个语言都有它自己的元对象协议，给出对象、类和元类如何交互的规则。
Smalltalk-80元类.
在Smalltalk中，所有东西都是对象。此外，Smalltalk是基于类的系统，这意味着所有对象都有一个类，它定义这个对象的结构（比如说这个类拥有实例变量），和这个对象所理解的消息。二者在一起蕴含了，在Smalltalk中，类是一个对象，因此类也需要是它的元类的实例。
元类在Smalltalk-80系统中的主要角色，是提供协议来初始化类变量，和建立元类的唯一实例（也就是其对应的类）的初始化实例。
实例联系.
为了允许类拥有它们自己的方法，和叫作类实例变量它们自己的，Smalltalk-80为每个类codice_1介入了它们自己的元类codice_2。就像实例方法实际上属于类一样，类方法实际上属于元类。在类中定义和，而在元类中定义类实例变量。
每个元类在效果上都是单例类。就像连体双胞胎，类和元类是共生的。元类有一个实例变量codice_3，它指向它结合的类。平常的Smalltalk，不将元类展示为单独的类，转而允许一起同时编辑类和它的元类。
要得到一个实例的类，需要向它发送消息调用codice_4方法。类和元类继承了其超类的codice_5方法，它返回接收者名字的字符串。例如，轿车对象codice_6是类codice_7的实例，则codice_8返回codice_7类对象，而codice_10返回codice_11；依次类推，codice_12返回codice_7的元类对象，而codice_14返回依赖于实现，有的是codice_15，即没有名字，有的是codice_16，即用空格分隔的类名字和codice_17。
在早期的Smalltalk-76中，创建新类的方式是向codice_18类发送codice_19消息。在Smalltalk-80中，codice_18是元类的基础类，它是类而不是元类。所有元类都是一个codice_21类的实例。codice_21类是codice_23的实例，而codice_23作为元类，也是codice_21类的实例。
继承联系.
在Smalltalk-80中，终端对象是一个整数、一个组件、或一台车等，而类是像codice_26、或codice_27或codice_7等这样的东西，除了codice_29之外，所有的类都有一个超类。元类所继承的元类，就是元类对应的类所继承的类的元类。
在一个消息被发送到对象的时候，方法的查找开始于它的类。如果没有找到则在上行超类链，停止于codice_29而不管找到与否。在一个消息被发送到一个类的时候，类方法查找开始于它的元类，并上行超类链至codice_31。直至codice_31，元类的超类层级并行于类的超类层级。在Smalltalk-80中，codice_31是codice_18的子类：
Object class superclass == Class.
类方法的查找在元类链之后仍可继续下去，所有元类都是codice_18的在继承层级中的子类，它是所有元类的抽象超类，它描述这些类的一般性质，继而最终可上溯至codice_29。
继承层级.
四个类提供描述新类的设施，下面是它们的继承层级（起自codice_29），和它们提供的主要设施：
例子.
下列例子展示，从Smalltalk-80派生的Squeak和Pharo的样例代码的结构，它们的继承层级的根类实际上是codice_78，codice_78封装了所有对象都必须拥有的极小化的消息集合，它被设计为引发尽可能多的错误，用来支持代理（proxy）定义。例如Smalltalk-80的codice_29中，错误处理消息codice_81，和系统原始消息codice_82，就转而在codice_78中定义了。
在示意图中，纵向的绿色连接，展示继承联系的“子→父”关系（隐含的自下而上），横向的蓝色连接展示实例联系的“成员→容器”关系，从codice_84出的发蓝色连接，指向codice_84的最小实际容器，它是在调用在codice_84上的方法时查找方法的继承链起点：
这个结构由两个部份构成，用户部份有四个显式的对象和类及其两个隐式的元类：终端对象codice_87和codice_88，它们连接到的类codice_89和codice_90，它们两个连接到的右侧灰色节点表示的隐式的元类，其他的对象都是内建部份。
方法查找次序.
下面是方法查找次序的辨析：
类图示意.
下面是两个示意图，二者都是纵向连线表示实例联系，而横向连线表示继承联系。实例联系以codice_21（元类类）及其元类为顶端，而继承联系以codice_29（对象类）及其元类为中心，其中codice_31（对象元类）继承codice_18（类类）是串接元类继承链与类继承链的关键环节。前者图示将codice_21及其元类放置在最上方的独立两行，使得实例联系尽量成为树状向上汇聚；后者图示将codice_21及其元类放置在最左边，使得继承联系尽量都在同一行之上。
Objective-C元类.
在Objective-C中的元类，几乎同于Smalltalk-80的元类，这是因为Objective-C从Smalltalk引进了很多东西。就像Smalltalk，在Objective-C中实例变量和方法是对象的类定义的。类也是对象，因此它是元类的一个实例。
就像Smalltalk，在Objective-C中类方法，简单的是在类对象上调用的方法，因此一个类的类方法，必须定义为在它的元类中的实例方法。因为不同的类有不同的类方法集合，每个类都必须有它自己单独的元类。类和元类总是成对创建：运行时系统拥有函数codice_111和codice_112来分别的创建和注册类-元类对。
元类没有名字，但是到任何类对象的指针，可以通过泛化类型codice_18来提及（类似于用作到任何对象的指针的类型codice_114）。
元类都是相同的类即根类元类的实例，而根类元类是自身的实例。因为类方法是通过继承联系来继承的，就像Smalltalk，除了根类元类之外，元类继承联系必须并行于类继承联系（比如说如果类A的父类是类B，则A的元类的父类是B的元类）。
不同于Smalltalk，根类元类继承自根类自身（通常为使用Cocoa框架的codice_115）。这确保了所有的元类最终都是根类的子类，从而人们可以将根类的实例方法，它们通常是针对对象有用的实用方法，使用于类对象自身上。
Python元类.
在Python中，内建的类codice_116是元类。Python中的元类codice_116，在其专有功能上涉及到Smalltalk-80中的类描述类（codice_51）、元类类（codice_21）和类类（codice_18）。
概述.
Python与Smalltalk-80在对象系统上最显著区别，是Python中类方法的创建由内建的类方法修饰器codice_121统一处理，经过修饰的类方法与实例方法以同样的方式存储在类中。由于不需要为每个类建立自己的元类来持有它的类方法，也就无需再特设Smalltalk-80中的元类类codice_21。每个类在创建自身子类时查找构造方法最终上溯到共同的一个类，它在Smalltalk-80中是类类codice_18，而在Python中就是类型类codice_116。
在Python中可以创建继承自缺省元类codice_116的定制元类，用户可以通过在类定义中提供关键字参数codice_126来使用这种定制元类。例如：
下面先建立辅助函数：
def review(cls):
 print(type(cls).__name__, 
 [x.__name__ for x in cls.__bases__])
def inspect(cls):
 print(type(cls).__name__, 
 [x.__name__ for x in cls.__bases__], 
 sorted([*cls.__dict__]))
再内省这个例子所建立的类与对象，和内建的所有类的基类codice_127与元类codice_116:
»&gt; print(type(b).__name__, ' '*5, [*b.__dict__])
B []
»&gt; inspect(B)
M ['A'] ['__doc__', '__firstlineno__', '__module__', '__static_attributes__', 'f']
»&gt; assert dir(b) == dir(B) == sorted(b.__dir__()) != sorted(B.__dir__(B))
»&gt; assert vars(B) == B.__dict__
»&gt; inspect(A)
M ['object'] ['__dict__', '__doc__', '__firstlineno__', '__module__', '__static_attributes__', '__weakref__']
»&gt; [x.__name__ for x in A.__subclasses__()]
['B']
»&gt; inspect(M)
type ['type'] ['__doc__', '__firstlineno__', '__module__', '__static_attributes__']
»&gt; assert type.__name__ in __builtins__.__dict__
»&gt; review(type)
type ['object']
»&gt; assert object.__name__ in __builtins__.__dict__
»&gt; review(object)
type []
»&gt; sorted({*object.__dict__} - {*type.__dict__})
['__class__', '__eq__', '__format__', '__ge__', '__getstate__', '__gt__', '__hash__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__reduce__', '__reduce_ex__', '__str__', '__subclasshook__']
»&gt; sorted({*object.__dict__} &amp; {*type.__dict__})
['__delattr__', '__dir__', '__doc__', '__getattribute__', '__init__', '__new__', '__repr__', '__setattr__', '__sizeof__']
»&gt; sorted({*type.__dict__} - {*object.__dict__})
['__abstractmethods__', '__annotations__', '__base__', '__bases__', '__basicsize__', '__call__', '__dict__', '__dictoffset__', '__flags__', '__instancecheck__', '__itemsize__', '__module__', '__mro__', '__name__', '__or__', '__prepare__', '__qualname__', '__ror__', '__subclasscheck__', '__subclasses__', '__text_signature__', '__type_params__', '__weakrefoffset__', 'mro']
»&gt; assert A.__subclasscheck__(B) is True
»&gt; assert object.__subclasscheck__(type) is True
»&gt; assert type.__subclasscheck__(type, M) is True
»&gt; assert B.__instancecheck__(b) is True
»&gt; assert M.__instancecheck__(M, B) is True
»&gt; assert type.__instancecheck__(type, M) is True
在Python的数据模型中：
接着内省标准类型中的实例方法类型，和对象特殊方法中的实行（implementing）描述器的方法codice_162：
»&gt; type(b.f)
&lt;class 'method'&gt;
»&gt; type(B.f)
&lt;class 'function'&gt;
»&gt; assert B.f is B.__dict__['f']
»&gt; sorted({*b.f.__dir__()} - {*B.f.__dir__()})
['__func__', '__self__']
»&gt; assert b.f.__func__ is B.f
»&gt; assert b.f.__self__ is b
»&gt; type(object.__subclasscheck__)
&lt;class 'builtin_function_or_method'&gt;
»&gt; sorted({*object.__subclasscheck__.__dir__()} - {*type.__subclasscheck__.__dir__()})
['__module__', '__self__']
»&gt; assert object.__subclasscheck__.__self__ is object
»&gt; assert object.__subclasscheck__.__module__ is None 
»&gt; type(type.__subclasscheck__)
&lt;class 'method_descriptor'&gt;
»&gt; sorted({*type.__subclasscheck__.__dir__()} - {*object.__subclasscheck__.__dir__()})
['__get__', '__objclass__']
»&gt; type(type.__subclasscheck__.__get__(object))
&lt;class 'builtin_function_or_method'&gt;
»&gt; assert type.__subclasscheck__.__get__(object)(type) is True
»&gt; type(object.__instancecheck__)
&lt;class 'builtin_function_or_method'&gt;
»&gt; type(type.__instancecheck__)
&lt;class 'method_descriptor'&gt;
抽象基类.
下面承接上例，内省内建类型codice_163、抽象基类codice_164和作为元类codice_116子类的抽象基类元类codice_133:
»&gt; assert int.__name__ in __builtins__.__dict__
»&gt; review(int)
type ['object']
»&gt; import numbers
»&gt; review(numbers.Integral)
ABCMeta ['Rational']
»&gt; [x.__name__ for x in numbers.Integral.__mro__]
['Integral', 'Rational', 'Real', 'Complex', 'Number', 'object']
»&gt; sorted({*numbers.Integral.__dict__} - {*int.__dict__})
['__abstractmethods__', '__firstlineno__', '__module__', '__slots__', '__static_attributes__', '_abc_impl']
»&gt; assert type.__subclasscheck__(numbers.Integral, int) is False
»&gt; assert type.__instancecheck__(numbers.Integral, 123) is False
»&gt; assert numbers.Integral.__subclasscheck__(int) is True
»&gt; assert numbers.Integral.__instancecheck__(123) is True
»&gt; assert numbers.Integral.__subclasshook__(int) is NotImplemented
»&gt; class MyInt(): pass
»&gt; numbers.Integral.register(MyInt)
&lt;class '__main__.MyInt'&gt;
»&gt; assert numbers.Integral.__subclasscheck__(MyInt) is True
»&gt; assert numbers.Integral.__instancecheck__(MyInt()) is True
»&gt; from abc import ABC, ABCMeta
»&gt; assert ABC.__subclasscheck__(numbers.Integral) is False
»&gt; review(ABC)
ABCMeta ['object']
»&gt; sorted({*ABC.__dict__} - {*A.__dict__})
['__abstractmethods__', '__slots__', '_abc_impl']
»&gt; ABC.__abstractmethods__
frozenset()
»&gt; assert type.__instancecheck__(ABCMeta, numbers.Integral) is True
»&gt; review(ABCMeta)
type ['type']
»&gt; sorted({*ABCMeta.__dict__} - {*M.__dict__})
['__instancecheck__', '__new__', '__subclasscheck__', '_abc_caches_clear', '_abc_registry_clear', '_dump_registry', 'register']
»&gt; [x.__module__+'.'+x.__qualname__ for x in type.__subclasses__(type)]
['abc.ABCMeta', 'enum.EnumType', 'ast._ABC', 'typing._AnyMeta', 'typing.NamedTupleMeta', 'typing._TypedDictMeta', '__main__.M']
静态方法与类方法.
Python中的静态方法和类方法修饰器，基于了非数据描述器协议，下面是静态方法描述器的纯Python等价者：
import functools
class StaticMethod():
 "模拟cpython/Objects/funcobject.c中的PyStaticMethod_Type()"
 def __init__(self, f):
 self.f = f
 functools.update_wrapper(self, f)
 def __get__(self, obj, objtype=None):
 return self.f
 def __call__(self, *args, **kwds):
 return self.f(*args, **kwds)
这里的codice_167直接返回所包装的函数codice_168，而codice_169以指定实际参数执行所包装的函数codice_168。
在Python中，类型和方法可以在运行时动态创建，下面是类方法描述器的纯Python等价者：
import functools
class ClassMethod():
 "模拟cpython/Objects/funcobject.c中的PyClassMethod_Type()"
 def __init__(self, f):
 self.f = f
 functools.update_wrapper(self, f)
 def __get__(self, obj, cls=None):
 if cls is None:
 cls = type(obj)
 return MethodType(self.f, cls)
这里的codice_167通过方法类型codice_172，在从类或从实例发起调用而有传入的类引用codice_173的常见情况下，建立将函数codice_168绑定到了codice_173上的方法对象；在没有传入的类引用的情况下，建立将函数codice_168绑定到了codice_177上的方法对象。
定制元类例子.
考虑下面这个最简单的Python类：
class Car():
 descr = None
 def __init__(self, *args, **kwargs):
 self.descr = kwargs
 def __call__(self, *args, **kwargs):
 self.descr |= kwargs
 @property
 def description(self):
 """返回这辆车的描述。"""
 return " ".join(str(value) for value in self.descr.values())
»&gt; new_car = Car(make='Toyota', model='Prius', year=2005, engine='Hybrid')
»&gt; new_car(color='Green')
»&gt; new_car.description
'Toyota Prius 2005 Hybrid Green'
上面的例子包含了一些代码来处理初始化特性，也可以使用元类来完成这种任务：
class AttrInitType(type):
 def __init__(cls, *args, **kwargs):
 """初始化新建的类。"""
 #为新建的类增加类特性。
 cls.descr = None 
 def __call__(cls, *args, **kwargs):
 """返回为所建的类新建的对象。"""
 #截留给类构造子的关键字参数，以缺省方式建立对象。
 obj = type.__call__(cls, *args) 
 #在对象初始化之后，按关键字参数在对象上设置特性。
 obj.descr = kwargs
 return obj
这个元类只覆写实例类和对象创建部份功能。元类行为的所有其他方面仍由codice_116处理。现在可以重写类codice_7使用这个新元类：
class Car(object, metaclass=AttrInitType):
 def __call__(self, *args, **kwargs):
 self.descr |= kwargs
 @property
 def description(self):
 """返回这辆车的描述。"""
 return " ".join(str(value) for value in self.descr.values())
Ruby元类.
Ruby通过介入其自称的本征类（eigenclass），提炼了Smalltalk-80的元类概念，去除了codice_21类，并重新定义了codice_181映射。变更可以图示如下：
特别要注意在Smalltalk的隐含的元类和Ruby类的本征类之间的对应。Ruby的本征类模型，使得隐式元类概念完全统一：所有对象codice_84，都有它自己的元对象，它叫作codice_84的本征类，它比codice_84高一个元层级。高阶本征类通常是纯粹概念上的存在，在大多数Ruby程序中，它们不包含任何方法也不存储任何（其他）数据。
下面的示意图展示Ruby样例代码的核心结构。这里的灰色节点表示打开codice_89和codice_88本征类后扩张出来的本征类。
图示还展示了Ruby中本征类的惰性求值。codice_88对象可以有它的本征类，作为向codice_88增加“单例方法”的结果而被求值（被分配）。
在语言和工具中的支持.
下面是支持元类的一些最显著的编程语言。
一些不甚广泛传播的语言支持元类，包括、OpenC++、OpenAda、、ObjVLisp、、MODEL-K、和MELDC。其中几种语言可追溯日期至1990年代早期并具有学术价值。
是Prolog的面向对象扩展，它也支持元类。
资源描述框架（RDF）和统一建模语言（UML）二者都支持元类。