我正在尝试确定python中调用函数的所属类。例如,我有两个类,即ClassA和ClassB。我想知道classb_instance.call_class_a_method()何时是class_a.class_a_method()的调用者,例如:

class ClassA(object):
    def class_a_method(self):
        # Some unknown process would occur here to
        # define caller.
        if caller.__class__ == ClassB:
            print 'ClassB is calling.'
        else:
            print 'ClassB is not calling.'

class ClassB(object):
    def __init__(self):
        self.class_a_instance = ClassA()
    def call_class_a_method(self):
        self.class_a_instance.class_a_method()

classa_instance = ClassA()
classa_instance.class_a_method()
classb_instance = ClassB()
classb_instance.call_class_a_method()

输出将是:
'ClassB is not calling.'
'ClassB is calling.'

似乎检查应该能够做到这一点,但是我不知道该怎么做。

最佳答案

一个函数没有“拥有”一个类-一个或多个类可以(但不必)引用给定的函数对象,例如:

def f(self): return g()

class One(object): bah = f

class Two(object): blup = f

def g(): ...
One.bahTwo.blup都被设置为对同一功能对象f的引用(当在类或它们的实例上访问时,它们变成未绑定(bind)或绑定(bind)的方法对象,但是在堆栈中不留痕迹)。因此,堆叠在
One().f()


Two().f()

从这两种情况下调用的g()来看,确实很难区分-例如,
f('blah bloh blup')

根本不涉及“类”(尽管用作fself参数的字符串的类型为;-)。

我建议而不是依靠内省(introspection)-尤其是野生和羊毛类,具有很多启发式功能,对于任何生产代码要求,这里都需要使用半启发式信息-重新构造以避免这种需求。

在这种情况下,出于纯粹调试的目的,您可以遍历堆栈,直到找到带有名为self的第一个参数的调用函数,并内省(introspection)绑定(bind)到该参数名称的值的类型,但是正如我提到的那样,这完全是启发性的,因为没有当且仅当它们的功能旨在作为某些类中的方法时,才强制调用者将其第一个参数命名为self

在我刚刚给出的三个代码示例中,这种启发式自省(introspection)会产生类型对象OneTwostr -如您所见,除调试之外,它肯定对其他方面没有多大好处;-)。

如果您通过尝试的自省(introspection)更好地明确说明您要完成的工作,那么我们当然可以为您提供更好的帮助。

09-04 02:46
查看更多