Как получить название функции python
Перейти к содержимому

Как получить название функции python

  • автор:

Функции и их аргументы

Python 3 логотип

В этой статье я планирую рассказать о функциях, именных и анонимных, инструкциях def, return и lambda, обязательных и необязательных аргументах функции, функциях с произвольным числом аргументов.

Именные функции, инструкция def

Функция в python — объект, принимающий аргументы и возвращающий значение. Обычно функция определяется с помощью инструкции def.

Определим простейшую функцию:

Инструкция return говорит, что нужно вернуть значение. В нашем случае функция возвращает сумму x и y.

Теперь мы ее можем вызвать:

 
  Функция может и не заканчиваться инструкцией return, при этом функция вернет значение None:

Функция может принимать произвольное количество аргументов или не принимать их вовсе. Также распространены функции с произвольным числом аргументов, функции с позиционными и именованными аргументами, обязательными и необязательными.

Функция также может принимать переменное количество позиционных аргументов, тогда перед именем ставится *:

    Как видно из примера, args - это кортеж из всех переданных аргументов функции, и с переменной можно работать также, как и с кортежем.

Функция может принимать и произвольное число именованных аргументов, тогда перед именем ставится **:

В переменной kwargs у нас хранится словарь, с которым мы, опять-таки, можем делать все, что нам заблагорассудится.

Анонимные функции, инструкция lambda

Анонимные функции могут содержать лишь одно выражение, но и выполняются они быстрее. Анонимные функции создаются с помощью инструкции lambda. Кроме этого, их не обязательно присваивать переменной, как делали мы инструкцией def func():

 

Для вставки кода на Python в комментарий заключайте его в теги

  • Модуль csv - чтение и запись CSV файлов
  • Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
  • Онлайн-обучение Python: сравнение популярных программ
  • Книги о Python
  • GUI (графический интерфейс пользователя)
  • Курсы Python
  • Модули
  • Новости мира Python
  • NumPy
  • Обработка данных
  • Основы программирования
  • Примеры программ
  • Типы данных в Python
  • Видео
  • Python для Web
  • Работа для Python-программистов
  • Сделай свой вклад в развитие сайта!
  • Самоучитель Python
  • Карта сайта
  • Отзывы на книги по Python
  • Реклама на сайте

Как в Python узнать имя функции в которой выполняется код?

Как в Python узнать имя функции в которой выполняется код? Желательно не устанавливая дополнительные модули. Например 1:

class Test: def func_1(): print(f'Print from ') def func_2(): print(f'Print from ') def func_3(): print(f'Print from ') test = Test() test.func_1() test.func_2() test.func_3() 
class Test: def func_1(): self.where_are_you() def func_2(): self.where_are_you() def func_3(): self.where_are_you() def where_are_you(): if current_func == 'func_1': print('Print from func_1') elif current_func == 'func_2': print('Print from func_2') elif current_func == 'func_2': print('Print from func_2') test = Test() test.func_1() test.func_2() test.func_3() 

При выполнении кода хочу видеть такой вывод:

Print from func_1
Print from func_2
Print from func_3

питон, можно ли узнать имя функции, вызвавшей текущую функцию?

Если допустим функция A вызывает функцию B, можно ли внутри B узнать кто её вызвал?

Или определить рекурсию, когда B вызывает сама себя, чтобы предотвратить зацикливание.

Пока на уме парсить трейсбек, но может есть способы цивильнее?

sergey-novikov ★★★
07.02.15 09:41:46 MSK

import inspect

Там есть уже распарсенный стек вызовов.

Как-то так: inspect.stack()[2][3]

E ★★★
( 07.02.15 10:05:27 MSK )
Ответ на: комментарий от E 07.02.15 10:05:27 MSK

спасибо
а имя функции по ходу вообще не узнать, только получить адрес фрейма из inspect.currentFrame() и сравнить с адресом в стеке?

sergey-novikov ★★★
( 07.02.15 10:34:36 MSK ) автор топика

Естественно, сделать такое без костылей можно только в нормальном языке. Например, в JS

 function f() function helper(f) helper(f) //>>>> [Function: helper] 

anonymous
( 07.02.15 10:55:16 MSK )
Ответ на: комментарий от sergey-novikov 07.02.15 10:34:36 MSK

Ты на inspect.stack() смотрел вообще? Там имена функций есть, в том числе и текущей.

Virtuos86 ★★★★★
( 07.02.15 11:09:14 MSK )
Ответ на: комментарий от anonymous 07.02.15 10:55:16 MSK

import inspect def foo(): return inspect.stack()[1][3] def helper(f): return f() print helper(foo) # helper 

Virtuos86 ★★★★★
( 07.02.15 11:24:00 MSK )
Ответ на: комментарий от Virtuos86 07.02.15 11:24:00 MSK

sergey-novikov ★★★
( 07.02.15 13:15:28 MSK ) автор топика

Или определить рекурсию, когда B вызывает сама себя, чтобы предотвратить зацикливание.

def func(val): try: print ('IN', val) if getattr(func, '_used', False): raise Exception('Recursive call') func._used = True func(val + 1) finally: func._used = False 

mashina ★★★★★
( 07.02.15 14:12:16 MSK )

Если допустим функция A вызывает функцию B, можно ли внутри B узнать кто её вызвал?

а можно узнать, зачем?

emulek ★
( 07.02.15 19:57:25 MSK )

Эм, inspect, но его использование считается антипаттерном. В частности по тому что он

1) не гарантирует обратной совместимости

2) может работать по-другому в других реализациях python (например, pypy)

3) можно легко всандалить очень сложные для отладки баги

Я думаю, разумнее редизайнить твоё приложение. Кстати, а что ты делаешь?

true_admin ★★★★★
( 08.02.15 16:03:17 MSK )
Ответ на: комментарий от emulek 07.02.15 19:57:25 MSK

Динамические петушки любят подобным заниматься вместо работы.

anonymous
( 08.02.15 18:33:07 MSK )
Ответ на: комментарий от emulek 07.02.15 19:57:25 MSK

В питоне не знаю, а вот в JS пригождается иногда

 function tuk_tuk() function static_whore_anon(f) function Emulek(f) static_whore_anon(tuk_tuk) Emulek(tuk_tuk) //>>>> Fuck off fuckin' fug //>>>> Welcome, bro. 

anonymous
( 08.02.15 20:25:18 MSK )
Ответ на: комментарий от anonymous 08.02.15 20:25:18 MSK

Проиграл с этого, например

Aswed ★★★★★
( 09.02.15 10:58:21 MSK )

Или определить рекурсию, когда B вызывает сама себя, чтобы предотвратить зацикливание.

Питон не зацикливается на рекурсии, если ты не трогаешь sys.setrecursionlimit.

xpahos ★★★★★
( 10.02.15 06:15:01 MSK )
Ответ на: комментарий от xpahos 10.02.15 06:15:01 MSK

Добавьте, пожалуйста, в Яндекс.Стор какой-нибудь IRC-клиент.

Как получить имя функции в виде строки?

Использование __name__ является предпочтительным методом, так как он применяется единообразно. В отличие от func_name , он также работает с встроенными функциями:

>>> import time >>> time.time.func_name Traceback (most recent call last): File "", line 1, in ? AttributeError: 'builtin_function_or_method' object has no attribute 'func_name' >>> time.time.__name__ 'time' 

Также двойное подчеркивание указывает на то, что для читателя это специальный атрибут. В качестве бонуса, классы и модули также имеют атрибут __name__ , поэтому вы помните только одно специальное имя.

Поделиться 01 ноября 2008 в 00:07
Чтобы получить имя текущей функции или метода изнутри, рассмотрите:

import inspect this_function_name = inspect.currentframe().f_code.co_name 

sys._getframe также работает вместо inspect.currentframe , хотя последний избегает доступа к приватной функции. Чтобы получить имя вызывающей функции, рассмотрите f_back как в inspect.currentframe().f_back.f_code.co_name . Если также используется mypy , он может пожаловаться на это:

ошибка: Пункт "None" из "Optional[FrameType]" не имеет атрибута "f_code"

Чтобы подавить вышеуказанную ошибку, рассмотрите:

import inspect import types from typing import cast this_function_name = cast(types.FrameType, inspect.currentframe()).f_code.co_name 

Поделиться 22 ноября 2012 в 13:59
Если вас также интересуют методы классов, в Python 3.3+ есть __qualname__ в дополнение к __name__ .

def my_function(): pass class MyClass(object): def method(self): pass print(my_function.__name__) # gives "my_function" print(MyClass.method.__name__) # gives "method" print(my_function.__qualname__) # gives "my_function" print(MyClass.method.__qualname__) # gives "MyClass.method" 

Поделиться 07 ноября 2017 в 10:48

my_function.func_name 

Также есть другие интересные свойства функций. Введите dir(func_name) , чтобы перечислить их. func_name.func_code.co_code - это скомпилированная функция, сохраненная как строка.

import dis dis.dis(my_function) 

отобразит код в почти читаемом для человека формате. 🙂
Поделиться 30 октября 2008 в 19:39
Эта функция вернет имя функции вызывающего человека.

def func_name(): import traceback return traceback.extract_stack(None, 2)[0][2] 

Это похоже на ответ Альберта Фонппа с дружественной оберткой.
Поделиться 21 декабря 2013 в 00:59

import inspect def foo(): print(inspect.stack()[0][3]) 
  • stack()[0] - это вызывающий метод
  • stack()[3] - это строковое имя метода

Поделиться 20 марта 2019 в 03:49

Мне нравится использовать декоратор функций. Я добавил класс, который также разрабатывает время функции. Предположим, что gLog является стандартным логгером Python:

class EnterExitLog(): def __init__(self, funcName): self.funcName = funcName def __enter__(self): gLog.debug('Started: %s' % self.funcName) self.init_time = datetime.datetime.now() return self def __exit__(self, type, value, tb): gLog.debug('Finished: %s in: %s seconds' % (self.funcName, datetime.datetime.now() - self.init_time)) def func_timer_decorator(func): def func_wrapper(*args, **kwargs): with EnterExitLog(func.__name__): return func(*args, **kwargs) return func_wrapper 

так что теперь все, что вам нужно сделать с вашей функцией, это декорировать ее и вуаля

@func_timer_decorator def my_func(): 

Поделиться 19 июля 2016 в 08:37

Вы просто хотите получить имя функции, вот простой код для этого. Допустим, у вас есть эти функции, определенные

def function1(): print "function1" def function2(): print "function2" def function3(): print "function3" print function1.__name__ 

вывод будет function1

Теперь допустим, у вас есть эти функции в списке

a = [function1 , function2 , funciton3] 

чтобы получить имя функций

for i in a: print i.__name__ 

function1
функция2
function3

Поделиться 16 марта 2018 в 14:21

В качестве расширения ответа @Демын, я создал некоторые утилитарные функции, которые печатают имя текущей функции и аргументы текущей функции:

import inspect import logging import traceback def get_function_name(): return traceback.extract_stack(None, 2)[0][2] def get_function_parameters_and_values(): frame = inspect.currentframe().f_back args, _, _, values = inspect.getargvalues(frame) return ([(i, values[i]) for i in args]) def my_func(a, b, c=None): logging.info('Running ' + get_function_name() + '(' + str(get_function_parameters_and_values()) +')') pass logger = logging.getLogger() handler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s [%(levelname)s] -> %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.INFO) my_func(1, 3) # 2016-03-25 17:16:06,927 [INFO] -> Running my_func([('a', 1), ('b', 3), ('c', None)]) 

Поделиться 25 марта 2016 в 21:21

sys._getframe() не гарантированно доступен во всех реализации Python (см. ссылку), вы можете использовать модуль traceback для того же, например,

import traceback def who_am_i(): stack = traceback.extract_stack() filename, codeline, funcName, text = stack[-2] return funcName 

Вызов stack[-1] вернет текущие сведения о процессе.

Поделиться 31 августа 2013 в 00:34

Я видел несколько ответов, которые использовали декораторы, хотя я чувствовал, что некоторые были немного расплывчатыми. Вот что я использую для регистрации имен функций, а также их соответствующих входных и выходных значений. Я адаптировал это здесь, чтобы просто распечатать информацию, а не создавать файл журнала и адаптировал его для применения к конкретному примеру OP.

def debug(func=None): def wrapper(*args, **kwargs): try: function_name = func.__func__.__qualname__ except: function_name = func.__qualname__ return func(*args, **kwargs, function_name=function_name) return wrapper @debug def my_function(**kwargs): print(kwargs) my_function() 

Поделиться 24 октября 2019 в 19:46

import inspect def my_first_function(): func_name = inspect.stack()[0][3] print(func_name) # my_first_function 
import sys def my_second_function(): func_name = sys._getframe().f_code.co_name print(func_name) # my_second_function 

Поделиться 02 декабря 2020 в 15:03

Вы можете получить имя функции в виде строки, используя специальную переменную __name__ .

def my_function(): pass print(my_function.__name__) # prints "my_function" 

Поделиться 05 февраля 2022 в 23:24

import sys fn_name = sys._getframe().f_code.co_name 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *