2009-11-21 24 views
6

Dưới đây là dự đoán của tôi, mà không làm việc:Làm thế nào một lớp cơ sở python cho biết liệu một lớp con đã ghi đè các phương thức của nó chưa?

class BaseClass(object): 
    def foo(self): 
     return 'foo' 
    def bar(self): 
     return 'bar' 
    def methods_implemented(self): 
     """This doesn't work...""" 
     overriden = [] 
     for method in ('foo', 'bar'): 
      this_method = getattr(self, method) 
      base_method = getattr(BaseClass, method) 
      if this_method is not base_method: 
       overriden.append(method) 
     return overriden 

class SubClass(BaseClass): 
    def foo(self): 
     return 'override foo' 

o = SubClass() 
o.methods_implemented() 

Lý tưởng nhất, methods_implemented() sẽ trở lại [ 'foo'].

Làm cách nào?

(Tại sao tôi muốn thực hiện việc này? Lớp cơ sở của tôi là lớp Tài nguyên HTTP có phương thức GET, POST, vv. Theo mặc định, chúng trả về 405 Phương thức không được triển khai. với tiêu đề Cho phép đặt thành các phương thức mà bất kỳ lớp con nào thực hiện.)

+4

Tại sao wiki này là cộng đồng? –

+5

Không chắc chắn lý do tại sao bạn muốn làm điều này. Trong bất kỳ phân cấp lớp nào, một lớp cơ sở không cần phải biết bất cứ điều gì về các lớp dẫn xuất. Nếu điều này là bắt buộc, ** có thể ** thiết kế của bạn cần được xem xét lại. – Steg

+4

Tôi đồng ý rằng đây không phải là wiki: sẽ có câu trả lời phù hợp và có thể được chấp nhận. Ngoài ra, tôi muốn nghe thêm về lý do tại sao bạn muốn làm điều này, không phải vì bạn không nên, nhưng bởi vì nó giống như một trong những giải pháp cho một vấn đề có giải pháp tốt hơn và rất khác ở một nơi khác. –

Trả lời

9

Có lẽ điều này?

>>> class BaseClass(object): 
...  def foo(self): 
...   return 'foo' 
...  def bar(self): 
...   return 'bar' 
...  def methods_implemented(self): 
...   """This does work.""" 
...   overriden = [] 
...   for method in ('foo', 'bar'): 
...    this_method = getattr(self, method) 
...    base_method = getattr(BaseClass, method) 
...    if this_method.__func__ is not base_method.__func__: 
...     overriden.append(method) 
...   return overriden 
... 
>>> class SubClass(BaseClass): 
...  def foo(self): 
...   return 'override foo' 
... 
>>> o = SubClass() 
>>> o.methods_implemented() 
['foo'] 

Điều này sẽ kiểm tra xem các đối tượng hàm phía sau phương thức bị ràng buộc có giống nhau hay không.

Lưu ý, trước Python 2.6, thuộc tính __func__ được đặt tên im_func.

+0

Điều này làm việc, ngoại trừ trong trình thông dịch python-2.5 của tôi, bạn cần kiểm tra im_func, chứ không phải __func__. Có lẽ bạn có thể đề cập đến điều đó trong câu trả lời của bạn. Cảm ơn. – Tenac

+1

Bạn được chào đón, mặc dù lần sau bạn có thể xem xét không đánh dấu các câu hỏi như thế này là 'cộng đồng wiki'. Những người trả lời thích nhận điểm của họ! –

0

Các phương pháp, mặc dù gọi cùng một đối tượng, KHÔNG phải là cùng một đối tượng. Bạn phải kiểm tra xem các hàm được bao bọc trong phương thức không liên kết có cùng một đối tượng hay không.

Tôi đang sử dụng 2.6 ở đây, vì vậy tôi cũng đã thay đổi lớp để kế thừa từ đối tượng.

>>> class BaseClass(object): 
...  def foo(self): 
...   return 'foo' 
...  def bar(self): 
...   return 'bar' 
...  def methods_implemented(self): 
...   """This doesn't work...""" 
...   overriden = [] 
...   for method in ('foo', 'bar'): 
...    this_method = getattr(self, method).__func__ 
...    base_method = getattr(BaseClass, method).__func__ 
...    if this_method is base_method: 
...     overriden.append(method) 
...   return overriden 
... 
>>> class SubClass(BaseClass): 
...  def foo(self): 
...   return 'override foo' 
... 
>>> o = SubClass() 
>>> o.methods_implemented() 
['bar'] 
Các vấn đề liên quan