【问题标题】:How can a python base class tell whether a sub class has overridden its methods?python 基类如何判断子类是否覆盖了它的方法?
【发布时间】:2009-11-21 22:27:31
【问题描述】:

这是我的猜测,它不起作用:

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 Method Not Implemented。它还有一个方法 OPTIONS 应该返回 200 响应标头 Allow 设置为任何子类实现的方法。)

【问题讨论】:

  • 为什么这是一个社区维基?
  • 不确定您为什么要这样做。在任何类层次结构中,不应要求基类了解派生类的任何信息。如果需要,也许您的设计需要重新考虑。
  • 我同意这不应该是 wiki:会有一个有效且可以接受的答案。另外,我很想了解更多关于您为什么要这样做的信息,不是因为您不应该这样做,而是因为这听起来像是解决问题的方法之一,而在其他地方却有更好且非常不同的解决方案。跨度>
  • 嗯,不是答案,但我认为应该是“...如果 ths_method not base_method ...”
  • HTTPResource 类从哪里来?我在 python 中找不到任何这样的野兽。

标签: python


【解决方案1】:

也许是这个?

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

【讨论】:

  • 这行得通,但在我的 python-2.5 解释器中,您需要检查 im_func,而不是 func。也许您可以在回答中提到这一点。谢谢。
  • 不客气,不过下次您可能会考虑不要将此类问题标记为community wiki。响应者喜欢得到他们的分数!
  • 修复python3:因为base_method没有绑定到对象实例,测试需要调整为if this_method.__func__ is not base_method:(去掉第二个__func__)。
【解决方案2】:

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

我这里用的是 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']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    相关资源
    最近更新 更多