¿Cómo obtener un nombre de función como una cadena en Python?


En Python, ¿cómo obtengo un nombre de función como una cadena sin llamar a la función?

def my_function():
    pass

print get_function_name_as_string(my_function) # my_function is not in quotes

Debería generar "my_function".

¿Está esto disponible en python? Si no, ¿alguna idea de cómo escribir get_function_name_as_string en Python?

Author: APerson, 2008-10-30

9 answers

my_function.__name__

Usando __name__ es el método preferido ya que se aplica uniformemente. A diferencia de func_name, también funciona con funciones integradas:

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

También los guiones bajos dobles indican al lector que este es un atributo especial. Como beneficio adicional, las clases y los módulos también tienen un atributo __name__, por lo que solo tiene que recordar un nombre especial.

 623
Author: user28409,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-01 00:07:17

También puedes usar

import sys
this_function_name = sys._getframe().f_code.co_name
 210
Author: Albert Vonpupp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-29 00:00:31
my_function.func_name

También hay otras propiedades divertidas de las funciones. Escriba dir(func_name) para listarlos. func_name.func_code.co_code es la función compilada, almacenada como una cadena.

import dis
dis.dis(my_function)

Mostrará el código en casi formato legible. :)

 36
Author: Markus Jarderot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-30 19:58:30

Esta función devolverá el nombre de la función que llama.

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

Es como la respuesta de Albert Vonpupp con un envoltorio amigable.

 28
Author: Demyn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-21 00:59:58

Sys._getframe () no está garantizado que esté disponible en todas las implementaciones de Python (ver ref), puede usar el módulo traceback para hacer lo mismo, por ejemplo.

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

   return funcName

Una llamada a stack[-1] devolverá los detalles del proceso actual.

 11
Author: sandyc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-31 00:45:54

Si también te interesan los métodos de clase, Python 3.3+ tiene __qualname__ además de __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"
 9
Author: lapis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-07 10:48:04

Me gusta usar un decorador de funciones. He añadido una clase, que también veces el tiempo de la función. Asume que gLog es un logger estándar de 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

Así que ahora todo lo que tienes que hacer con tu función es decorarla y voila

@func_timer_decorator
def my_func():
 8
Author: radato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-19 08:37:30

Como una extensión de @ Demyn's answer , creé algunas funciones de utilidad que imprimen el nombre de la función actual y los argumentos de la función actual:

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)])
 7
Author: Jim G.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:22

Solo desea obtener el nombre de la función aquí hay un código simple para eso. digamos que tienes estas funciones definidas

def function1():
    print "function1"

def function2():
    print "function2"

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

La salida será function1

Ahora digamos que tienes estas funciones en una lista

a = [function1 , function2 , funciton3]

Para obtener el nombre de las funciones

for i in a:
    print i.__name__

La salida será

Function1
function2
function3

 2
Author: Muhammad Mohsin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-16 14:21:11