有没有办法在Python中识别继承的方法?

19 投票
5 回答
7612 浏览
提问于 2025-04-17 04:13

我想区分一下继承的方法和重载或新定义的方法。在Python中,这可能吗?

举个例子:

class A(object):
  def spam(self):
    print 'A spam'
  def ham(self):
    print 'A ham'

class B(A):
  def spam(self):
    print 'Overloaded spam'
  def eggs(self):
    print 'Newly defined eggs'

我想要的功能:

>>> magicmethod(B.spam)
'overloaded'
>>> magicmethod(B.ham)
'inherited'
>>> magicmethod(B.eggs)
'newly defined'

有没有什么“魔法方法”,或者其他方法可以帮助我区分这些不同类型的方法实现呢?

5 个回答

6

一种通用的方法是(适用于 Python 2.*):

def _getclass(method):
    try:
        return method.im_class
    except AttributeError:
        return method.__class__

def magicmethod(method):
    method_cls = _getclass(method)
    if method.__name__ not in method_cls.__dict__:
        return 'inherited'
    for cls in method_cls.__mro__[1:]:
        if method.__name__ in cls.__dict__:
            return 'overloaded'
    return 'newly defined'


__test__ = {"example": """

    >>> class A(object):
    ...     def spam(self):
    ...         print 'A spam'
    ...     def ham(self):
    ...         print 'A ham'

    >>> class B(A):
    ...     def spam(self):
    ...         print 'Overloaded spam'
    ...     def eggs(self):
    ...         print 'Newly defined eggs'

    >>> magicmethod(B.spam)
    'overloaded'
    >>> magicmethod(B.ham)
    'inherited'
    >>> magicmethod(B.eggs)
    'newly defined'
    >>> magicmethod(B.__init__)
    'inherited'
"""}
8

如果你知道祖先类,可以直接测试一下:

>>> B.spam == A.spam
False
>>> B.ham == A.ham
True

想要查看所有基类的列表,可以去这里看看:列出给定类的所有基类?

我还想提醒你,如果你需要这样做,可能说明你的类设计有问题。在面向对象编程中,你不应该太在意这些事情(除非你是在做一个对象检查器之类的工具)。

21

我不太确定这样做是否合适,但你可能可以通过使用 hasattr__dict__ 来实现。

def magicmethod(clazz, method):
    if method not in clazz.__dict__:  # Not defined in clazz : inherited
        return 'inherited'
    elif hasattr(super(clazz), method):  # Present in parent : overloaded
        return 'overloaded'
    else:  # Not present in parent : newly defined
        return 'newly defined'

撰写回答