Как получить имя вызывающего класса внутри функции другого класса в python?

моя цель-стимулировать диаграмму последовательности приложения для этого мне нужна информация об именах вызывающего и вызываемого классов во время выполнения. Я могу успешно получить функцию вызывающего абонента, но не могу получить имя класса вызывающего абонента?

#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()

когда я печатал стек, не было никакой информации о классе вызывающего. Таким образом, можно ли получить класс caller во время выполнения ?

4 ответов


Ну, после некоторого копания в подсказке, вот что я получаю:

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()

при вызове:

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

данного файла 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()

не уверен, как он будет вести себя при вызове из нечто иное, чем объект.


используя ответ от Python: как получить информацию о классе из объекта "frame"?

Я получаю что-то вроде этого...

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()

что дает мне следующий результат:

Hello
dude
<class '__main__.A'>

очевидно, что это возвращает ссылку на сам класс. Если вам нужно имя класса, вы можете получить это из .

к сожалению, это не будет работать для класса или статические методы ...


возможно, это нарушает какой-то протокол программирования Python, но если плохо всегда собираюсь проверить класс звонящего, почему не проходит абонента __class__ это, как вызов?

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()

результат:

Hello
dude
Calling class: __main__.A

если это плохая форма, и с помощью inspect действительно является предпочтительным способом получить класс звонящего, пожалуйста, объясните, почему. Я все еще изучаю более глубокие концепции Python.


чтобы сохранить имя экземпляра класса из стека в переменную класса:

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

этой

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

выведет:

myClassInstance1