2011-08-09 40 views
6

Vì vậy, tôi đang viết một số mã và gần đây đã đi qua sự cần thiết phải thực hiện một vài mixin. Câu hỏi của tôi là, cách thích hợp để thiết kế một mix-in là gì? Tôi sẽ sử dụng mã ví dụ bên dưới để minh họa cho truy vấn chính xác của mình.Python MixIn tiêu chuẩn

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 

Về cơ bản, tôi đang tự hỏi, là sự pha trộn-ins loại giống như giao diện Java, nơi có một loại (trong trường hợp tiềm ẩn của Python) hợp đồng rằng nếu người ta muốn sử dụng mã người ta phải xác định các biến nhất định/chức năng (không giống như một khung công tác), hoặc nó giống như mã tôi đã viết ở trên, trong đó mỗi kết hợp phải được khởi tạo một cách rõ ràng?

+0

Tôi không biết rằng đây là quy tắc nhưng không bình thường trong Python có '__init__'ing phi tuyến tính. Tôi sẽ giới hạn một lớp cơ sở, cha mẹ "đúng", để có và '__init__' phương pháp. Ngoài ra, như ví dụ của bạn được viết, bạn không bao giờ gọi 'Bounded.update()'. – agf

+0

Vâng, đã viết ví dụ lên một chút quá nhanh. Tuy nhiên, về điểm của bạn về __init__, điều đó có gợi ý rằng các mix-in không phải là __init__ (trong trường hợp này, chúng có hợp đồng) không? –

+0

Tôi thực sự không biết về "nên không" - nhưng trong Python, nó chắc chắn là cách tôi sẽ làm điều đó. Tôi không đăng nó như một câu trả lời vì đó là một ý kiến. Tôi không chắc chắn bạn sẽ nhận được một câu trả lời cho điều này mà _isn't_ ý kiến ​​(bên dưới là chỉ off-topic) vì vậy hãy cho tôi biết nếu bạn muốn đăng bài này như là một câu trả lời. – agf

Trả lời

2

Bạn có thể có cả hai hành vi bằng Python. Bạn có thể ép buộc việc thực thi lại bằng cách sử dụng các lớp cơ sở trừu tượng, hoặc bằng cách nâng cao NotImplementedError trong các hàm ảo.

Nếu init rất quan trọng trong lớp học của cha mẹ, thì bạn phải gọi cho họ. Như eryksun đã nói, hãy sử dụng hàm dựng sẵn super để gọi trình khởi tạo của cha mẹ (theo cách này, trình khởi tạo cho một lớp nhất định sẽ chỉ được gọi một lần).

Kết luận: phụ thuộc vào những gì bạn có. Trong trường hợp của bạn, bạn phải gọi init và bạn nên sử dụng super.