python基类如何判断子类是否覆盖了它的方法?

时间:2009-11-21 22:27:31

标签: 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()会返回['foo']。

如何?

(我为什么要这样做?我的基类是一个HTTP资源类,它有方法GET,POST等。默认情况下它们返回405方法未实现。它还有一个方法OPTIONS,它应返回200响应标头允许设置为任何子类实现的方法。)

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

即使调用同一个对象,这些方法也不是同一个对象。您必须进行测试以查看未绑定方法中包含的函数是否是同一个对象。

我在这里使用2.6,所以我也改变了类继承自object。

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