【问题标题】:In Python, class from which a given instance is inheriting a particular method在 Python 中,给定实例从中继承特定方法的类
【发布时间】:2014-03-06 08:25:43
【问题描述】:

我知道在 Python 中,给定一个类 ClassA,带有

inspect.getmembers(ClassA, predicate=inspect.ismethod)

我可以迭代ClassA 中存在的不同方法。还收集了继承的方法,这对我来说很方便。但是我需要的是,给定ClassA 的特定方法method1,以获取ClassA 继承method1 的类。它可能是ClassA 本身,或者它的任何父母/祖父母。我以为我可以递归遍历__bases__ 属性,在每一步寻找method1 属性。但也许这个功能已经在某个地方实现了。还有其他方法吗?

【问题讨论】:

    标签: python inheritance introspection


    【解决方案1】:

    查看 MRO(方法解析顺序),使用 inspect.getmro()(适用于新旧类):

    def class_for_method(cls, method):
        return next((c for c in inspect.getmro(cls) 
                     if method.__func__ in vars(c).values()), None)
    

    目前没有 stdlib 方法可以为您执行此搜索,没有。

    演示:

    >>> import inspect
    >>> def class_for_method(cls, method):
    ...     return next((c for c in inspect.getmro(cls) 
    ...                  if method.__func__ in vars(c).values()), None)
    ... 
    >>> class Base1(object):
    ...     def foo(self): pass
    ... 
    >>> class Base2(object):
    ...     pass
    ... 
    >>> class ClassA(Base1, Base2):
    ...     pass
    ... 
    >>> class_for_method(ClassA, ClassA.foo)
    <class '__main__.Base1'>
    

    如果没有找到基类,上面的表达式返回None

    >>> class Bar:
    ...     def spam(): pass
    ... 
    >>> class_for_method(ClassA, Bar.spam) is None
    True
    

    【讨论】:

    • 我测试了它,它正是我需要的。不知道getmro。谢谢!
    • @zeycus:我已经对其进行了一些改进,以便在面对被覆盖的方法时更加健壮;它只会找到 exact 方法来自的基类,即使您传入的方法现在已被后来的基类覆盖。
    • 再次感谢,我会使用改进版。这些微妙之处远远超出了我目前的 OOP Python 知识。
    猜你喜欢
    • 1970-01-01
    • 2017-05-14
    • 2011-10-05
    • 2013-11-10
    • 2019-06-01
    • 2010-11-08
    • 2015-10-26
    • 1970-01-01
    • 2015-02-15
    相关资源
    最近更新 更多