Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

My objective is to stimulate a sequence diagram of an application for this I need the information about a caller and callee class names at runtime. I can successfully retrieve the caller function but not able to get a caller class name?

#Scenario caller.py:

import inspect

class A:

    def Apple(self):
        print "Hello"
        b=B()
        b.Bad()



class B:

    def Bad(self):
        print"dude"
        print inspect.stack()


a=A()
a.Apple()

When I printed the stack there was no information about the caller class. So is it possible to retrieve the caller class during runtime ?

like image 234
Kaushik Avatar asked Jun 12 '13 12:06

Kaushik


People also ask

How do I get the name of a class call in Python?

To get the class name of an instance in Python: Use the type() function and __name__ to get the type or class of the Object/Instance. Using the combination of the __class__ and __name__ to get the type or class of the Object/Instance.

How do you call a class method from another class method in Python?

Call method from another class in a different class in Python. we can call the method of another class by using their class name and function with dot operator. then we can call method_A from class B by following way: class A: method_A(self): {} class B: method_B(self): A.

Can we call a method outside of class in Python?

The variables that are defined inside the class but outside the method can be accessed within the class(all methods included) using the instance of a class. For Example – self. var_name. If you want to use that variable even outside the class, you must declared that variable as a global.


2 Answers

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_name

print("I was called by {}.{}()".format(the_class, the_method))
# => I was called by A.a()

When invoked:

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

given the file test.py:

import inspect

class 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.

like image 158
brice Avatar answered Oct 19 '22 00:10

brice


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

I get something like this...

import inspect

def 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 None


class 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:

Hello
dude
<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 ...

like image 7
mgilson Avatar answered Oct 19 '22 01:10

mgilson