2009-11-21 93 views
6

這裏是我的猜測,這是不行的:python基類如何判斷子類是否覆蓋了它的方法?

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() 

理想的情況下,methods_implemented()將返回[ '富'。

怎麼樣?我爲什麼要這樣做?我的基類是一個HTTP資源類,它具有GET,POST等方法。默認情況下,它們返回405 Method Not Implemented方法,它還有一個OPTIONS方法,它應該返回一個200響應頭部允許設置爲任何子類實現的方法。)

+4

爲什麼這是社區wiki? – 2009-11-21 22:35:41

+5

不知道你爲什麼想要這樣做。在任何類層次結構中,不應要求基類知道有關派生類的任何內容。如果這是必需的,**也許**您的設計需要重新考慮。 – Steg 2009-11-21 22:37:05

+4

我同意這不應該是維基:將有一個有效的答案,可以接受。 另外,我希望瞭解更多關於爲什麼要這樣做的原因,不是因爲你不應該這樣做,而是因爲它聽起來像是解決某個問題的解決方案之一,而這個問題在其他地方有一個更好的和非常不同的解決方案。 – 2009-11-21 22:55:54

回答

9

也許這樣?

>>> 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'] 

這將檢查綁定方法後面的函數對象是否相同。

請注意,在Python 2.6之前,__func__屬性被命名爲im_func

+0

這有效,除了在我的python-2.5解釋器中,你需要檢查im_func而不是__func__。也許你可以在你的答案中提到這一點。謝謝。 – Tenac 2009-11-22 00:12:43

+1

不客氣,但下次您可能會考慮不將此類問題標記爲「社區wiki」。響應者喜歡獲得他們的觀點! – 2009-11-22 02:16:54

0

即使調用同一個對象,這些方法也不是同一個對象。您必須測試以查看包裝在未綁定方法中的函數是否是同一個對象。

我在這裏使用2.6,所以我也將類更改爲從對象繼承。

>>> 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'] 
相關問題