How to get the caller class name inside a function of another class in python? How to get the caller class name inside a function of another class in python? python python

How to get the caller class name inside a function of another class in python?


Well, after some digging at the prompt, here's what I get:

stack = inspect.stack()the_class = stack[1][0].f_locals["self"].__class__.__name__the_method = stack[1][0].f_code.co_nameprint("I was called by {}.{}()".format(the_class, the_method))# => I was called by A.a()

When invoked:

➤ python test.pyA.a()B.b()  I was called by A.a()

given the file test.py:

import inspectclass A:  def a(self):    print("A.a()")    B().b()class B:  def b(self):    print("B.b()")    stack = inspect.stack()    the_class = stack[1][0].f_locals["self"].__class__.__name__    the_method = stack[1][0].f_code.co_name    print("  I was called by {}.{}()".format(the_class, the_method))A().a()

Not sure how it will behave when called from something other than an object.


Using the answer from Python: How to retrieve class information from a 'frame' object?

I get something like this...

import inspectdef get_class_from_frame(fr):  args, _, _, value_dict = inspect.getargvalues(fr)  # we check the first parameter for the frame function is  # named 'self'  if len(args) and args[0] == 'self':    # in that case, 'self' will be referenced in value_dict    instance = value_dict.get('self', None)    if instance:      # return its class      return getattr(instance, '__class__', None)  # return None otherwise  return Noneclass A(object):    def Apple(self):        print "Hello"        b=B()        b.Bad()class B(object):    def Bad(self):        print"dude"        frame = inspect.stack()[1][0]        print get_class_from_frame(frame)a=A()a.Apple()

which gives me the following output:

Hellodude<class '__main__.A'>

clearly this returns a reference to the class itself. If you want the name of the class, you can get that from the __name__ attribute.

Unfortunately, this won't work for class or static methods ...


Perhaps this is breaking some Python programming protocol, but if Bad is always going to check the class of the caller, why not pass the caller's __class__ to it as part of the call?

class A:    def Apple(self):        print "Hello"        b=B()        b.Bad(self.__class__)class B:    def Bad(self, cls):        print "dude"        print "Calling class:", clsa=A()a.Apple()

Result:

HellodudeCalling class: __main__.A

If this is bad form, and using inspect truly is the preferred way to get the caller's class, please explain why. I'm still learning about deeper Python concepts.