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

别等时光非礼了梦想. 提交于 2019-11-27 12:24:31

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

stack = inspect.stack()
the_class = stack[1][0].f_locals["self"].__class__
the_method = stack[1][0].f_code.co_name

print("I was called by {}.{}()".format(str(calling_class), calling_code_name))
# => I was called by A.a()

When invoked:

➤ python test.py
A.a()
B.b()
  I was called by __main__.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__
    the_method = stack[1][0].f_code.co_name
    print("  I was called by {}.{}()".format(str(the_class), the_method))

A().a()

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

mgilson

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

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:", cls


a=A()
a.Apple()

Result:

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

To store class instance name from the stack to class variable:

import inspect

class myClass():

    caller = ""

    def __init__(self):
        s = str(inspect.stack()[1][4]).split()[0][2:]
        self.caller = s

    def getInstanceName(self):
        return self.caller

This

myClassInstance1 = myClass()
print(myClassInstance1.getInstanceName())

will print:

myClassInstance1

Instead of indexing the return value of inspect.stack(), one could use the method inspect.currentframe(), which avoids the indexing.

prev_frame = inspect.currentframe().f_back
the_class = prev_frame.f_locals["self"].__class__
the_method = prev_frame.f_code.co_name
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!