4

我无法完成以下功能:

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 )

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

4

1 回答 1

1

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

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

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

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

您还需要考虑一些障碍:

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

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

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

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

于 2013-05-16T14:11:23.783 回答