关于运行以下代码的行为,我有两个问题。为什么在没有实例化对象的情况下调用__new__
?我认为__new__
控制了新实例的创建。接下来,当delattr
为 size 返回 True 时,为什么hasattr
会引发 AttributeError ?
class ShapeBase(type):
def __new__(cls, name, bases, attrs):
rv = super(ShapeBase, cls).__new__(cls, name, bases, attrs)
parents = [base for base in bases if isinstance(base, ShapeBase)]
# don't do anything unless this is a subclass of Shape
if not parents:
return rv
print hasattr(rv, 'altitude') # prints True
print rv.altitude # prints 7
del rv.altitude # deletes altitude from rv
print hasattr(rv, 'size') # prints True
print rv.size # prints 5
delattr(rv, 'size') # raises AttributeError
return rv
class Shape(object):
__metaclass__ = ShapeBase
size = 5
class Triangle(Shape):
altitude = 7
答案 0 :(得分:4)
__new__
控制新类的实例化,而不是该类的新实例。因此,当您使用Shape
作为元类创建类ShapeBase
时,会调用ShapeBase.__new__
。
答案 1 :(得分:3)
对于第二个问题delattr(rv, 'size')
(和del rv.size
)失败,因为属性size
是一个类属性而不是一个实例属性,它意味着是类__dict__
的一部分不是实例__dict__
。
hasattr
通常会返回True
,因为它会在传递给它的对象的所有父类中搜索一个属性。
为什么在评估类主体时调用元类__new__
时会想到这样:
如果创建类的实例,则在创建实例时将调用类
__new__
,是吗?因此同样适用于类,元类是类的类,因此在创建类时将调用__new__
。