В Python, без использования traceback
модуля, есть ли способ определить имя функции из этой функции?
Скажем, у меня есть модуль foo с функциональной панелью. При выполнении foo.bar()
, есть ли способ для бара узнать имя бара? Или еще лучше, foo.bar
как зовут?
#foo.py
def bar():
print "my name is", __myname__ # <== how do I calculate this at runtime?
python
function
introspection
traceback
обкрадывать
источник
источник
traceback
. Даже времена ответов и комментариев, кажется, не подтверждают это.Ответы:
Python не имеет возможности доступа к функции или ее имени внутри самой функции. Это было предложено, но отклонено. Если вы не хотите играть со стеком самостоятельно, вы должны либо использовать,
"bar"
либо вbar.__name__
зависимости от контекста.Данное уведомление об отказе:
источник
inspect.currentframe()
это один из таких способов.print(inspect.currentframe().f_code.co_name)
источник
[1][3]
можете узнать имя звонящего.print(inspect.currentframe().f_code.co_name)
или получить имя вызывающего абонента:print(inspect.currentframe().f_back.f_code.co_name)
. Я думаю, что это должно быть быстрее, так как вы не получаете список всех кадров стека, как этоinspect.stack()
происходит.inspect.currentframe().f_back.f_code.co_name
не работает с декорированным методом, в то времяinspect.stack()[0][3]
как ...Есть несколько способов получить тот же результат:
Обратите внимание, что
inspect.stack
вызовы в тысячи раз медленнее, чем альтернативы:источник
inspect.currentframe()
кажется хорошим компромиссом между временем исполнения и использованием частных членов0.100 usec
или ,0.199 usec
но в любом случае - в сотни раз быстрее , чем варианты 1 и 2, сравнимых с опцией 4 (хотя Энтони Hatchkins нашел вариант 3 в три раза быстрее , чем вариант 4).sys._getframe().f_code.co_name
болееinspect.currentframe().f_code.co_name
просто потому , что я уже импортировалsys
модуль. Это разумное решение? (учитывая, что скорости выглядят довольно похоже)Вы можете получить имя, для которого оно было определено, используя подход, который показывает @Andreas Jung , но это может быть не то имя, с которым была вызвана функция:
Важно ли это различие для вас или нет, я не могу сказать.
источник
.func_name
. Стоит помнить, что имена классов и функций в Python - это одно, а переменные, ссылающиеся на них, - другое.Foo2()
распечататьFoo
. Например:Foo2 = function_dict['Foo']; Foo2()
. В этом случае Foo2 является указателем на функцию, возможно, для анализатора командной строки.Я хотел очень похожую вещь, потому что я хотел поместить имя функции в строку журнала, которая вошла в ряд мест в моем коде. Возможно, это не лучший способ сделать это, но вот способ получить имя текущей функции.
источник
f
для кадра иco
для кода. Я не пользуюсь этим, так что лучше, если я простоЯ держу эту удобную утилиту поблизости:
Применение:
источник
Я думаю,
inspect
это лучший способ сделать это. Например:источник
Я нашел оболочку, которая напишет имя функции
Это напечатает
источник
my_funky_name.__name__
. Вы можете передать func .__ name__ в функцию в качестве нового параметра. func (* args, ** kwargs, my_name = func .__ name__). Чтобы получить имя вашего декоратора из вашей функции, я думаю, что для этого потребуется использовать inspect. Но получение названия функции, управляющей моей функцией, в рамках моей функции бега ... ну, это звучит как начало красивого мема :)Это на самом деле вытекает из других ответов на вопрос.
Вот мой дубль:
Вероятное преимущество этой версии по сравнению с использованием inspect.stack () состоит в том, что она должна быть в тысячи раз быстрее [см. Сообщение Алекса Мелихоффа о времени использования sys._getframe () по сравнению с использованием inspect.stack ()].
источник
print(inspect.stack()[0].function)
кажется, тоже работает (Python 3.5).источник
Вот подход, ориентированный на будущее.
Сочетание предложений @ CamHart и @ Yuval с принятым ответом @ RoshOxymoron позволяет избежать:
_hidden
и потенциально устаревшие методыПоэтому я думаю, что это хорошо работает с будущими версиями Python (протестировано на 2.7.3 и 3.3.2):
источник
Тестовое задание:
Вывод:
источник
Я не уверен, почему люди делают это сложным:
источник
В IDE код выводит
источник
Вы можете использовать декоратор:
источник
__name__
атрибута функции. Использование требует знания того, что вы пытаетесь получить, что не кажется мне очень полезным в простых случаях, когда функции не определены на лету.Я делаю свой собственный подход, используемый для вызова супер с безопасностью в сценарии множественного наследования (я поместил весь код)
пример использования:
тестирую это:
вывод:
Внутри каждого украшенного метода @with_name у вас есть доступ к self .__ fname__ в качестве текущего имени функции.
источник
Недавно я попытался использовать приведенные выше ответы для доступа к строке документации функции из контекста этой функции, но поскольку приведенные выше вопросы возвращали только строку имени, это не сработало.
К счастью, я нашел простое решение. Если, как и я, вы хотите обратиться к функции, а не просто получить строку, представляющую имя, которую вы можете применить eval () к строке имени функции.
источник
Я предлагаю не полагаться на элементы стека. Если кто-то использует ваш код в разных контекстах (например, интерпретатор Python), ваш стек изменится и нарушит ваш индекс ([0] [3]).
Я предлагаю вам что-то подобное:
источник
Это довольно легко сделать с помощью декоратора.
источник