Python __new__具有继承的元类行为

时间:2011-07-15 13:17:41

标签: python inheritance metaprogramming

关于运行以下代码的行为,我有两个问题。为什么在没有实例化对象的情况下调用__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

2 个答案:

答案 0 :(得分:4)

元类的

__new__控制新类的实例化,而不是该类的新实例。因此,当您使用Shape作为元类创建类ShapeBase时,会调用ShapeBase.__new__

答案 1 :(得分:3)

对于第二个问题delattr(rv, 'size')(和del rv.size)失败,因为属性size是一个类属性而不是一个实例属性,它意味着是类__dict__的一部分不是实例__dict__

hasattr通常会返回True,因为它会在传递给它的对象的所有父类中搜索一个属性。

为什么在评估类主体时调用元类__new__时会想到这样:

  

如果创建类的实例,则在创建实例时将调用类__new__,是吗?因此同样适用于类,元类是类的类,因此在创建类时将调用__new__