【问题标题】:Does a metaclass instantiate the class's attributes first?元类是否首先实例化类的属性?
【发布时间】:2013-01-08 10:26:40
【问题描述】:

this answer 到“什么是元类?”我得到了这个:

你先写了 class Foo(object),但是 class 对象 Foo 还没有在内存中创建。

Python 将在类定义中查找 metaclass。如果找到它,它将使用它来创建对象类 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

【问题讨论】:

    标签: python python-2.7 metaclass


    【解决方案1】:

    类体是在类构建之前运行的,是的。

    类的主体提供了一个临时命名空间,该命名空间中的所有本地名称都以字典的形式给出,以构造类对象,以及基类和类的名称。

    您也可以使用 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}
    

    【讨论】:

      猜你喜欢
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 2018-05-15
      • 1970-01-01
      相关资源
      最近更新 更多