我正在尝试确定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.bah
和Two.blup
都被设置为对同一功能对象f
的引用(当在类或它们的实例上访问时,它们变成未绑定(bind)或绑定(bind)的方法对象,但是在堆栈中不留痕迹)。因此,堆叠在One().f()
与
Two().f()
从这两种情况下调用的
g()
来看,确实很难区分-例如,f('blah bloh blup')
根本不涉及“类”(尽管用作
f
的self
参数的字符串的类型为;-)。我建议而不是依靠内省(introspection)-尤其是野生和羊毛类,具有很多启发式功能,对于任何生产代码要求,这里都需要使用半启发式信息-重新构造以避免这种需求。
在这种情况下,出于纯粹调试的目的,您可以遍历堆栈,直到找到带有名为
self
的第一个参数的调用函数,并内省(introspection)绑定(bind)到该参数名称的值的类型,但是正如我提到的那样,这完全是启发性的,因为没有当且仅当它们的功能旨在作为某些类中的方法时,才强制调用者将其第一个参数命名为self
。在我刚刚给出的三个代码示例中,这种启发式自省(introspection)会产生类型对象
One
,Two
和str
-如您所见,除调试之外,它肯定对其他方面没有多大好处;-)。如果您通过尝试的自省(introspection)更好地明确说明您要完成的工作,那么我们当然可以为您提供更好的帮助。