如何在python中的另一个类的函数内获取调用者类名?

时间:2021-05-20 01:45:44

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 ?

当我打印堆栈时,没有关于调用者类的信息。那么可以在运行时检索调用者类吗?

4 个解决方案

#1


27  

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:

给出文件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.

不确定从对象以外的其他东西调用时它的行为方式。

#2


4  

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

使用Python的答案:如何从'frame'对象中检索类信息?

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.

很明显,这会返回对类本身的引用。如果需要类的名称,可以从__name__属性获取该名称。

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

不幸的是,这对于类或静态方法不起作用......

#3


3  

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?

也许这打破了一些Python编程协议,但如果Bad总是要检查调用者的类,为什么不将调用者的__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()

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.

如果这是不好的形式,并且真正使用检查是获得呼叫者课程的首选方式,请解释原因。我还在学习更深入的Python概念。

#4


0  

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

#1


27  

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:

给出文件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.

不确定从对象以外的其他东西调用时它的行为方式。

#2


4  

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

使用Python的答案:如何从'frame'对象中检索类信息?

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.

很明显,这会返回对类本身的引用。如果需要类的名称,可以从__name__属性获取该名称。

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

不幸的是,这对于类或静态方法不起作用......

#3


3  

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?

也许这打破了一些Python编程协议,但如果Bad总是要检查调用者的类,为什么不将调用者的__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()

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.

如果这是不好的形式,并且真正使用检查是获得呼叫者课程的首选方式,请解释原因。我还在学习更深入的Python概念。

#4


0  

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