web-dev-qa-db-fra.com

Obtenir le nom de la fonction de l'appelant dans une autre fonction en Python?

Si vous avez 2 fonctions comme:

def A
def B

et A appelle B, pouvez-vous savoir qui appelle B dans B, comme:

def A () :
    B ()

def B () :
    this.caller.name
105
Joan Venge

Vous pouvez utiliser le module inspect pour obtenir les informations souhaitées. Sa méthode pile renvoie une liste d'enregistrements de trames.

  • Pour Python 2 chaque enregistrement de trame est une liste. Le troisième élément de chaque enregistrement est le nom de l'appelant. Ce que vous voulez c'est:

    >>> import inspect
    >>> def f():
    ...     print inspect.stack()[1][3]
    ...
    >>> def g():
    ...     f()
    ...
    >>> g()
    g
    

  • Pour Python 3.5 + , chaque enregistrement de trame est un nommé Tuple donc vous devez remplacer

    print inspect.stack()[1][3]
    

    avec

    print(inspect.stack()[1].function)
    

    sur le code ci-dessus.

159
Ayman Hourieh

Il existe deux façons d'utiliser les modules sys et inspect:

  • sys._getframe(1).f_code.co_name
  • inspect.stack()[1][3]

La forme stack() est moins lisible et dépend de l'implémentation car elle appelle sys._getframe(), voir extrait de 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)
22
Eric

Remarque (juin 2018): aujourd'hui, j'utiliserais probablement le module inspect, voir les autres réponses

sys._getframe(1).f_code.co_name comme dans l'exemple ci-dessous:

>>> def foo():
...  global x
...  x = sys._getframe(1)
...
>>> def y(): foo()
...
>>> y()
>>> x.f_code.co_name
'y'
>>>  

Remarque importante: comme il ressort de la _getframe nom de la méthode (hé, ça commence par un trait de soulignement), ce n'est pas une méthode d'API sur laquelle on devrait compter sans réfléchir.

13
Piotr Findeisen

Ça marche pour moi! :RÉ

>>> def a():
...     import sys
...     print sys._getframe(1).f_code.co_name
...
>>> def b():
...     a()
...
...
>>> b()
b
>>>
7
Alex Cory

vous pouvez utiliser le module de journalisation et spécifier l'option% (funcName) s dans 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')
3
mescalin