WedX - журнал о программировании и компьютерных науках

Получение имени функции вызывающего абонента внутри другой функции в Python?

Если у вас есть 2 функции, например:

def A
def B

и A звонит B, вы можете узнать, кто звонит B внутри B, например:

def A () :
    B ()

def B () :
    this.caller.name
22.05.2009

  • У вас есть доступный источник. Зачем вам такая вещь? 23.05.2009
  • Потому что я отлаживаю код в интерпретаторе python стороннего приложения, где нет настоящего отладчика. 25.05.2009
  • По теме: Как записать имя исходного файла и номер строки в Python. 25.09.2018
  • Пометить это как дубликат, поскольку другой имеет больше просмотров и голосов по этому вопросу. 30.08.2019

Ответы:


1

Вы можете использовать модуль 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)
    

    в приведенном выше коде.

22.05.2009
  • на python 3.4, по крайней мере, это не работает, они изменили порядок кортежей. В настоящее время используется именованный кортеж, поэтому лучше всего использовать inspect.stack () [1] .filename 23.03.2016
  • На самом деле, вы, вероятно, захотите inspect.currentframe().f_back.f_code.co_name, который не зависит от версии или реализации Python. 29.05.2019
  • @ 1313e: также inspect.currentframe() зависит от реализации Python, поскольку, если вы читаете исходный код inspect.py, они оба используют sys._getframe() 23.10.2019
  • благодаря. также обнаружил, что .filename также может помочь, когда однозначно .function. например: print(inspect.stack()[1].function, inspect.stack()[1].filename) 23.02.2020
  • Может ли он также напечатать полный путь к функции? 11.12.2020

  • 2

    Есть два способа использования модулей 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)
    
    28.01.2015
  • Является ли sys._getframe (1) .f_code.co_name сравнительно быстрее, чем inspect.stack () [1] [3]? 20.08.2018
  • Прежде чем спешить спросить, вы пробовали рассчитать время (например, с помощью timeit)? Я думаю, что это быстрее, потому что, похоже, он не требует вызовов функций и двух поисков по списку. Но в Python кое-что можно спрятать, поэтому лучше всего timeit это сделать. Дайте нам знать, что вы найдете. 21.08.2018
  • Я хотел знать почему, потому что знал, что это быстрее. И я не ценю кажущиеся ответы. 21.08.2018
  • (getframe) 0.00419473648071: (inspect) 29.3846197128 Вот соотношение между двумя для 4000 вызовов. 21.08.2018
  • Отличная находка! Я предполагаю, что использование CPython и Python версии 2 или 3 не сильно влияет на результат. Спасибо за выполнение теста. 22.08.2018

  • 3

    Примечание (июнь 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, на который следует бездумно полагаться.

    22.05.2009
  • sys._getframe не гарантируется, что он существует во всех реализациях Python - Я думаю, это важно отметить. 25.09.2011

  • 4

    У меня это работает! : D

    >>> def a():
    ...     import sys
    ...     print sys._getframe(1).f_code.co_name
    ...
    >>> def b():
    ...     a()
    ...
    ...
    >>> b()
    b
    >>>
    
    22.07.2016
  • Это отлично работает, но сначала это сбивало с толку, потому что вы могли просто использовать функцию b (), отображающую ее собственное имя. Другие ответы, говорящие об использовании inspect., с треском провалились, потому что он не был определен. Думаю, авторы забыли заявление о зависимости. 09.09.2020

  • 5

    вы можете использовать модуль регистрации и указать параметр% (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')
    
    24.07.2012
  • Вы случайно сказали %(filename)s option. Это должно быть то, что у вас есть в примере кода: %(funcName)s :) 08.08.2014
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]