为何元类Meta创建的WithAttr类,type输出为type而非Meta?
问题解答
首先看给出的代码:
class Meta(type): def __new__(cls, name, bases, dct): new_class = type(name, bases, dct) new_class.attr = 100 # add some to class return new_class class WithAttr(metaclass=Meta): pass print(type(WithAttr)) # <class 'type'>
为什么输出是<class 'type'>而非<class '__main__.Meta'>?
问题出在元类Meta的__new__方法实现上:
- 元类的核心作用是生成类对象,正常情况下,元类创建类应该通过自身(也就是
cls,即Meta)来实例化,比如用super().__new__(cls, name, bases, dct)或者直接cls(name, bases, dct)。 - 但这段代码里,
new_class是直接调用type(name, bases, dct)生成的——type是所有类的默认元类,这样创建出来的类对象直接属于type,和Meta元类没有了实例关系。 - 简单说,代码绕开了
Meta自身的构造逻辑,直接用默认元类type造了类,所以type(WithAttr)返回的是type。
WithAttr类是否是Meta的实例?
不是。你可以用isinstance(WithAttr, Meta)验证,结果会是False。
原因和上面一致:WithAttr是type()直接创建的实例,而非通过Meta元类构造出来的。如果要让它成为Meta的实例,需要修改Meta的__new__方法,改成用cls来创建类,比如:
class Meta(type): def __new__(cls, name, bases, dct): new_class = super().__new__(cls, name, bases, dct) # 或者 new_class = cls(name, bases, dct) new_class.attr = 100 return new_class
这时再运行print(type(WithAttr))就会输出<class '__main__.Meta'>,isinstance(WithAttr, Meta)也会返回True。
内容的提问来源于stack exchange,提问作者mikeziminio
相关产品推荐
相关产品推荐

