从检查堆栈中获取完全限定的方法名称

and*_*ykx 6 python

我无法完成以下功能:

def fullyQualifiedMethodNameInStack(depth=1):
    """
    The function should return <file>_<class>_<method> for the method in the 
    stack at specified depth.
    """
    fileName=inspect.stack()[depth][1]
    methodName=inspect.stack()[depth][3]
    class= """ please help!!! """
    baseName=os.path.splitext( os.path.basename( fileName ) )[0]
    return '{0}_{1}_{2}'.format( baseName, className, methodName )
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我想要正在执行的方法的类名。Inspect返回的堆栈只有方法名,不知道如何找到属于该方法的类。

Mar*_*ers 3

你总是在查看函数上下文;当函数执行时,方法上下文已经消失了。从技术上讲,函数在作为实例 ( instance.method_name) 上的属性进行访问时充当描述符,返回一个方法对象。然后,方法对象在被调用时,依次调用原始函数,并将实例作为第一个参数。由于这一切都发生在 C 代码中,因此 Python 堆栈上不会保留原始方法对象的痕迹。

堆栈只需要跟踪命名空间以及要为本地命名空间执行的代码。这些函数不再需要原始函数对象,只有附加的代码对象仍然保留原始函数定义的名称以用于回溯目的。

如果您知道该函数是方法,则可以搜索self本地名称。如果存在,则是实例type(self)的类,它不一定是定义方法的类。

然后,您必须搜索该类及其基础(循环属性.__mro__)以尝试找到定义该方法的类。

您还需要考虑一些其他问题:

  • 命名方法的第一个参数self只是一种约定。如果有人选择了不同的名称,那么您将无法在不亲自解析 Python 源代码的情况下弄清楚这一点,或者通过在堆栈中向上执行另一个步骤并尝试从行推断出该函数是如何被调用的,然后检索该方法它的.im_self属性。

  • 您只会获得定义该函数的原始名称。这不一定是调用它的名称。函数是一等对象,可以添加到不同名称的类中。

  • 尽管函数被传入self并被定义为类定义的一部分,但它可以通过手动传入值来调用self,而不是通过传入方法的通常路径(作为函数作为描述符的结果)传入self调用者的参考。

在 Python 3.3 及更高版本中,情况稍微好一些;函数对象有一个新__qualname__属性,其中包含类名。那么问题是您仍然需要从父堆栈帧中找到函数对象。