Стандарты Python MixIn - PullRequest
       19

Стандарты Python MixIn

6 голосов
/ 10 августа 2011

Итак, я пишу код и недавно столкнулся с необходимостью реализации нескольких миксинов.Мой вопрос в том, как правильно создать микс?Я буду использовать приведенный ниже пример кода, чтобы проиллюстрировать мой точный запрос.

class Projectile(Movable, Rotatable, Bounded):
    '''A projectile.'''
    def __init__(self, bounds, position=(0, 0), heading=0.0):
        Movable.__init__(self)
        Rotatable.__init__(self, heading)
        Bounded.__init__(self, bounds)
        self.position = Vector(position)

    def update(self, dt=1.0):
        '''Update the state of the object.'''
        scalar = self.velocity
        heading = math.radians(self.heading)
        direction = Vector([math.sin(heading), math.cos(heading)])
        self.position += scalar * dt * direction
        Bounded.update(self)

class Bounded(object):
    '''A mix-in for bounded objects.'''
    def __init__(self, bounds):
        self.bounds = bounds

    def update(self):
        if not self.bounds.contains(self.rect):
            while self.rect.top > self.bounds.top:
                self.rect.centery += 1
            while self.rect.bottom < self.bounds.bottom:
                self.rect.centery += 1
            while self.rect.left < self.bounds.left:
                self.rect.centerx += 1
            while self.rect.right > self.bounds.right:
                self.rect.centerx -= 1

По сути, мне интересно, являются ли встраиваемые модули подобными Java-интерфейсам, где есть своего рода (в неявном случае Python) договориться о том, что если кто-то хочет использовать код, он должен определить определенные переменные / функции (не в отличие от фреймворка), или это больше похоже на код, который я написал выше, где каждое дополнение должно быть явно инициализировано?

1 Ответ

2 голосов
/ 11 августа 2011

Вы можете иметь оба поведения в Python. Вы можете принудительно переопределить, используя абстрактные базовые классы или вызывая NotImplementedError в виртуальных функциях.

Если init важны в родительских классах, вам нужно их вызвать. Как сказал eryksun, используйте встроенную функцию super для вызова инициализаторов родителя (таким образом, инициализатор для данного класса будет вызываться только один раз).

Вывод: зависит от того, что у тебя есть. В вашем случае вам нужно позвонить init , и вы должны использовать super.

...