从this answer到“什么是元类?”我明白了:
首先编写类Foo(对象),但类对象Foo尚未在内存中创建。
Python将在类定义中查找元类。如果找到它,它将使用它来创建对象类Foo。如果没有,它将使用type来创建类。
测试之后,似乎在运行类的构造函数之前实例化了类的属性。我误解了什么?
测试代码:
class meta(type):
def __init__(cls, name, bases, dic):
type.__init__(cls, name, bases, dic)
print hasattr(cls, "a")
cls.a = "1"
class A(object):
a = "a"
__metaclass__ = meta
class B(object):
__metaclass__ = meta
class C(object):
__metaclass__ = meta
a = "a"
print A.a
print B.a
print C.a
输出:
True
False
True
1
1
1
答案 0 :(得分:4)
在构造类之前运行类主体,是的。
该类的主体提供临时命名空间,该命名空间中的所有本地名称都作为字典给出,以构造类对象,以及基类和类的名称。
您也可以使用type()
构造函数执行此操作:
>>> Foo = type('Foo', (), {'a': 1})
>>> Foo.a
1
类主体基本上作为一个函数执行,该函数的本地名称空间用于创建类属性,即上面type()
的第三个参数。
在python 3中,使用元类上的__prepare__
hook对该过程产生更多影响。 __prepare__
应该是一个类方法,它返回类主体的初始名称空间;在执行类主体之前,使用它在生成的类主体中注入额外的名称:
class MyMeta(type):
@classmethod
def __prepare__(mcl, name, bases):
return {'a': 1}