Python __new__ метакласс поведения с наследованием - PullRequest
0 голосов
/ 15 июля 2011

У меня есть два вопроса относительно поведения запуска приведенного ниже кода.Почему __new__ даже вызывается без создания объекта?Я думал, что __new__ контролировал создание нового экземпляра .Далее, почему delattr вызывает AttributeError , когда hasattr возвращает True для размер ?

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 ]

4 голосов
/ 15 июля 2011

__new__ метакласса управляет созданием нового класса, а не нового экземпляра этого класса. Поэтому, когда вы создаете класс Shape с ShapeBase в качестве метакласса, вызывается ShapeBase.__new__.

3 голосов
/ 15 июля 2011

Для второго вопроса delattr(rv, 'size')del rv.size) терпит неудачу, потому что атрибут size является атрибутом класса, а не атрибутом экземпляра, что означает, что он является частью класса __dict__, а не экземпляром __dict__.

И hasattr обычно возвращает True, поскольку он ищет атрибут во всех родительских классах объекта, переданного ему.

Что касается того, почему ваш метакласс __new__ вызывается при оценке тела класса, подумайте об этом так:

Если вы создаете экземпляр класса, класс __new__ будет вызываться при создании экземпляра, да? то же самое должно применяться к классу, метакласс - это класс класса, поэтому при создании класса будет вызываться __new__.

...