实际调用的是什么类(classname,instance)?

时间:2015-07-01 15:49:20

标签: python

我已经在Stack Overflow上看到了一堆python方法解析顺序问题,其中很多都得到了极好的回答。我有一个不太合适的。

当请求super(MyClassName, self).method_name时,我得到一个(单个)父类没有返回的类型。将调试放入父类会显示它没有被命中。

我会添加一些代码片段,但代码库很大。我已经进入了从MyClassName.__mro__列出的每个类(它告诉我们方法解析顺序是什么),并且它们中没有一个返回我得到的类型。所以问题是......

我可以使用Python中的哪个工具或属性来查找实际调用的代码,这样如果再次发生这种情况,我可以很容易地找出实际调用的内容?我最终找到了解决方案,但我宁愿知道如何以较少劳动密集的方式解决这个问题。

2 个答案:

答案 0 :(得分:1)

您可以使用例如inspect.getmodule,根据其文档:

  

尝试猜测对象的定义位置。

一个简单的例子,a.py

class Parent(object):

    def method(self):
        return True

b.py

import inspect

from a import Parent

class Child(Parent):

    def method(self):
        parent_method = super(Child, self).method  # get the parent method
        print "inherited method defined in {}".format(
            inspect.getmodule(parent_method),  # and find out where it came from
        )
        return parent_method()


if __name__ == '__main__':
    Child().method()

运行b.py会得到结果:

Parent defined in <module 'a' from 'C:/Python27\a.py'>

答案 1 :(得分:0)

我认为你可能会对绑定方法和方法解析顺序之间产生混淆。

返回的方法仍然算作实际对象的类的绑定方法,即使派生自的类的函数在父类中找到。这是因为该方法已绑定到子类的实例而不是父类。

例如

class A:
    def f(self):
        return "A"
class B(A):
    def g(self):
        return super().f
class C(B):
    def f(self):
        return "C"

c = C()
method = c.g()
print(method) # prints <bound method C.f of <__main__.C object at 0x02D4FA10>>
print(method()) # prints A

在这种情况下,c.g()返回绑定到A.f实例的函数C

要查找绑定方法将调用的实际函数,只需检查__func__属性:

assert method.__func__ is A.f