Если у вас есть 2 функции, например:
def A
def B
и A звонит B, вы можете узнать, кто звонит B внутри B, например:
def A () :
B ()
def B () :
this.caller.name
Если у вас есть 2 функции, например:
def A
def B
и A звонит B, вы можете узнать, кто звонит B внутри B, например:
def A () :
B ()
def B () :
this.caller.name
Вы можете использовать модуль inspect, чтобы получить нужную информацию. Его метод stack возвращает список записей кадра.
Для Python 2 каждая запись кадра представляет собой список. Третий элемент в каждой записи - это имя вызывающего абонента. Что вы хотите:
>>> import inspect
>>> def f():
... print inspect.stack()[1][3]
...
>>> def g():
... f()
...
>>> g()
g
Для Python 3.5+ каждая запись кадра представляет собой названный кортеж, поэтому вам нужно заменить
print inspect.stack()[1][3]
с участием
print(inspect.stack()[1].function)
в приведенном выше коде.
Есть два способа использования модулей sys
и inspect
:
sys._getframe(1).f_code.co_name
inspect.stack()[1][3]
Форма stack()
менее читаема и зависит от реализации, поскольку вызывает sys._getframe()
, см. Отрывок из inspect.py
:
def stack(context=1):
"""Return a list of records for the stack above the caller's frame."""
return getouterframes(sys._getframe(1), context)
timeit
)? Я думаю, что это быстрее, потому что, похоже, он не требует вызовов функций и двух поисков по списку. Но в Python кое-что можно спрятать, поэтому лучше всего timeit
это сделать. Дайте нам знать, что вы найдете. 21.08.2018 Примечание (июнь 2018 г.): сегодня я, вероятно, использовал бы модуль inspect
, см. другие ответы
sys._getframe(1).f_code.co_name
как в примере ниже:
>>> def foo():
... global x
... x = sys._getframe(1)
...
>>> def y(): foo()
...
>>> y()
>>> x.f_code.co_name
'y'
>>>
Важное примечание: как видно из _getframe
имени метода (эй, оно начинается с подчеркивания), это не метод API, на который следует бездумно полагаться.
У меня это работает! : D
>>> def a():
... import sys
... print sys._getframe(1).f_code.co_name
...
>>> def b():
... a()
...
...
>>> b()
b
>>>
inspect.
, с треском провалились, потому что он не был определен. Думаю, авторы забыли заявление о зависимости. 09.09.2020 вы можете использовать модуль регистрации и указать параметр% (funcName) s в BaseConfig ()
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')
%(filename)s option
. Это должно быть то, что у вас есть в примере кода: %(funcName)s
:) 08.08.2014
inspect.currentframe().f_back.f_code.co_name
, который не зависит от версии или реализации Python. 29.05.2019inspect.currentframe()
зависит от реализации Python, поскольку, если вы читаете исходный кодinspect.py
, они оба используютsys._getframe()
23.10.2019print(inspect.stack()[1].function, inspect.stack()[1].filename)
23.02.2020