如何让Python基类判断子类是否重写了其方法?

8 投票
2 回答
2854 浏览
提问于 2025-04-15 16:14

这是我猜的,但并没有成功:

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 响应,并且在头部中设置 Allow,列出任何子类实现的方法。)

2 个回答

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

也许可以这样做?

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

撰写回答