从inspect stack获取完全限定的方法名称

时间:2013-05-16 14:01:08

标签: 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 )

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

1 个答案:

答案 0 :(得分:1)

您总是在查看功能上下文;方法上下文在函数执行时已经消失。从技术上讲,functions act as descriptors作为实例(instance.method_name)上的属性进行访问,返回方法对象。然后,方法对象在被调用时,将实例作为第一个参数调用原始函数。因为这一切都发生在C代码中,所以Python栈上没有原始方法对象的痕迹。

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

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

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

还需要考虑一些障碍:

  • 命名方法self的第一个参数只是一个约定。如果有人选择了不同的名字,你将无法在不自己解析Python源代码的情况下解决这个问题,或者在堆栈的另一个步骤中尝试从那个行推导出函数如何被调用,然后检索方法,它是.im_self属性。

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

  • 虽然函数在self中传递并被定义为类定义的一部分,但它可以由手动调用传入{{1}的值而不是方法的通常路由(作为函数作为描述符的结果)传入调用者的self引用。

在Python 3.3及更高版本中,情况稍微好一点;函数对象有一个新的__qualname__ attribute,其中包含类名。问题是你仍然需要从父堆栈框架中找到函数对象。