2009-05-22 5 views
74

Si vous avez 2 fonctions comme:Obtenir le nom de la fonction appelant dans une autre fonction en Python?

def A 
def B 

et A appelle B, pouvez-vous qui appelle B à l'intérieur B, comme:

def A() : 
    B() 

def B() : 
    this.caller.name 
+1

Vous avez la source disponible. Pourquoi auriez-vous besoin d'une telle chose? –

+12

Parce que je débogue le code dans l'interpréteur python d'une application tierce où il n'y a pas de vrai débogueur. –

+3

duplication possible de [Python: comment obtenir le nom de la méthode de l'appelant dans la méthode appelée?] (Http://stackoverflow.com/questions/2654113/python-how-to-get-the-callers-method-name-in -the-called-method) – bernie

Répondre

103

Vous pouvez utiliser le module inspect pour obtenir l'appel empiler. Il renvoie une liste d'enregistrements de cadres. Le troisième élément de chaque enregistrement est le nom de l'appelant. Ce que vous voulez est le suivant:

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

Bien sûr, il est une bonne idée de vérifier que les dossiers assez cadre existent avant d'essayer d'accéder à un index particulier.

+6

sur python 3.4 au moins cela ne fonctionne pas, ils ont changé l'ordre des tuples. Un tuple nommé est maintenant utilisé, il est donc préférable d'utiliser inspect.stack() [1] .filename – timeyyy

8

comme dans l'exemple ci-dessous:

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

Note importante: comme il est évident à partir du nom de la méthode _getframe (hey, il commence par un trait de soulignement), ce n'est pas une méthode API on devrait compter inconsidérément sur .

+9

[sys._getframe] (http://docs.python.org/library/sys.html#sys._getframe) est "pas garanti d'exister dans toutes les implémentations de Python" - Je pense que c'est important de noter. – RWS

+0

@RWS, merci, noté –

2

vous pouvez l'utilisateur du module d'enregistrement et spécifiez le% (nom de fichier) l'option 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') 
+1

Par inadvertance, vous dites 'option% (filename) s'. Cela devrait être ce que vous avez dans votre exemple de code: '% (funcName) s' :) –

10

Il y a deux façons, en utilisant sys et inspect modules:

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

La forme stack() est moins lisible et est mise en œuvre dépend, car il appelle sys._getframe(), voir extrait 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) 
4

Cela fonctionne pour moi! : D

>>> def a(): 
...  import sys 
...  print sys._getframe(1).f_code.co_name 
... 
>>> def b(): 
...  a() 
... 
... 
>>> b() 
b 
>>> 
Questions connexes