关于调试:在Python的另一个函数中获取调用者函数名?

Getting the caller function name inside another function in Python?

如果您有两个功能,如:

1
2
def A
def B

A打B,你能知道B里面谁打B吗,比如:

1
2
3
4
5
def A () :
    B ()

def B () :
    this.caller.name


您可以使用Inspect模块获取所需的信息。它的堆栈方法返回一个帧记录列表。

  • 对于python 2,每个帧记录都是一个列表。每个记录中的第三个元素是调用方名称。你想要的是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> import inspect
    >>> def f():
    ...     print inspect.stack()[1][3]
    ...
    >>> def g():
    ...     f()
    ...
    >>> g()
    g
  • 对于python 3.5+,每个帧记录都是一个命名的元组,因此需要替换

    1
    print inspect.stack()[1][3]

    具有

    1
    print(inspect.stack()[1].function)

    上面的代码。


使用sysinspect模块有两种方法:

  • sys._getframe(1).f_code.co_name
  • inspect.stack()[1][3]

stack()形式可读性较差,且依赖于实现,因为它调用sys._getframe(),见inspect.py摘录:

1
2
3
def stack(context=1):
   """Return a list of records for the stack above the caller's frame."""
    return getouterframes(sys._getframe(1), context)


注(2018年6月):今天,我可能会使用inspect模块,见其他答案。

sys._getframe(1).f_code.co_name类似于下面的示例:

1
2
3
4
5
6
7
8
9
10
>>> def foo():
...  global x
...  x = sys._getframe(1)
...
>>> def y(): foo()
...
>>> y()
>>> x.f_code.co_name
'y'
>>>

重要提示:从_getframe方法名中可以明显看出(嘿,它以下划线开头),它不是一个应该轻率依赖的API方法。


这对我有用!D

1
2
3
4
5
6
7
8
9
10
11
>>> def a():
...     import sys
...     print sys._getframe(1).f_code.co_name
...
>>> def b():
...     a()
...
...
>>> b()
b
>>>

您可以使用日志模块并在baseconfig()中指定%(funcname)s选项。

1
2
3
4
5
import logging
logging.basicConfig(filename='/tmp/test.log', level=logging.DEBUG, format='%(asctime)s | %(levelname)s | %(funcName)s |%(message)s')

def A():
    logging.info('info')