2011-08-09 25 views
6

私はいくつかのコードを書いており、最近いくつかのミックスインを実装する必要性を抱えています。私の質問は、ミックスインを設計する適切な方法は何ですか?下のサンプルコードを使用して、正確なクエリを説明します。基本的にはPython MixInの標準

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 

、私は思ったんだけど、契約(Pythonの場合、暗黙の内)ソートの一種があるJavaインターフェースのようなミックスインは、1つのコードを使用したい場合は、1つは、特定の変数を定義しなければならないということです/ (フレームワークと違っていない)、あるいは私が上で書いたコードのように、それぞれのミックスインを明示的に初期化する必要がありますか?

+0

これはルールではありませんが、Pythonでは非線形の '__init__ 'を持つことは珍しいことです。私は "真の"親である1つの基本クラスを持つことと '__init__'メソッドに制限します。また、あなたの例が書かれているように、あなたは決して 'Bounded.update()'を呼び出すことはありません。 – agf

+0

ええ、あまりにも速い例を書きました。しかし、__init__についてのあなたの点に関しては、それはミックスインが__init__にする必要はないと示唆していますか(その場合、彼らは契約を持っています)? –

+0

私は本当に「いけない」とは知らないのですが、Pythonではそれは確かに私がやる方法です。私はそれが意見だったので答えとして掲示しなかった。私は、あなたがこれを回答として投稿したいのかどうかを私に知らせてください。 – agf

答えて

2

あなたは両方の動作をPythonで行うことができます。抽象基本クラスを使用するか、仮想関数でNotImplementedErrorを発生させることで、再実装を強制することができます。

が親クラスで重要な場合は、それらを呼び出す必要があります。 eryksunによると、組み込み関数superを使用して親のイニシャライザを呼び出します(この方法では、指定されたクラスのイニシャライザは一度呼び出されます)。

結論:あなたが持っているものによって異なります。あなたの場合は、に電話する必要があります。superを使用してください。