Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

obtenir le nom *complet* de la fonction dans laquelle je suis

+1 vote

Existe-t-il un moyen pour que le code suivant :

import traceback

def log(message):
    print "-----------------"
    print "%s: %s" %(traceback.extract_stack()[0:-1][-1][2], message)

def f1():
    log("salut")

class cls(object):

    def f1(self):
        log("coucou")

f1()

mycls = cls()
mycls.f1()

affiche :

-----------------
f1: salut
-----------------
cls.f1: coucou

au lieu de

-----------------
f1: salut
-----------------
f1: coucou

?

demandé 28-Jul par Julien

2 Réponses

0 votes

Quelque chose comme ça (pas certain que ça soit très stable) :

def log(message):
    stack = traceback.extract_stack()[0:-1]
    func = stack[0][-1][:-2]
    try:
        # Function
        func_name = globals()[func].__name__
    except KeyError:
        # Class method
        parts = func.split('.')
        class_name = globals()[parts.pop(0)].__class__.__name__
        func_name = '.'.join([class_name, '.'.join(parts)])

    print '-----------------'
    print '%s: %s' %(func_name, message)

Autre solution :

def log(message):
    print('-----------------')
    print('%s: %s' % (
        inspect.stack()[-1][-2][0].strip().replace('()', ''),
        message)
    )
répondu 30-Jul par Tiger-222 (492 points)
edité 5-Aou par Tiger-222

Cette solution n'est pas stable car elle ilmplique de parser la ligne de python où log est appelée.
Dans l'exemple l'appel est très simple, donc ça fonctionne, mais si quelque part j'écris :

(f8() if (f2(mycls1.f3(f4(5 + varx), [y for y in range(10) if (f5(y) > 3)])) == "Hello") else f9(f10(f11() + f12(f13(8) + f14()))))

c'est foutu... Il faudrait réécrire un parser python en entier :S

J'avais pensé à utiliser le module inspect mais il me manque un chainon dans la chaine des transformations du traceback vers le nom complet de la fonction courante.

Ca fait un paquet de functions et méthodes ça :)
J'ai ajouté une seconde solution en utilisant le module inspect. Peut-être pourrais-tu fournir toutes ces fonctions/classe/méthodes pour tester en réel, car c'est un exemple bien complexe.

0 votes
traceback.extract_stack()[0][-1]

renvoit l'info que tu cherches.

répondu 4-Aou par Laurent

Même réponse que précédemment :
Pour n'importe quel élément 'frame' de traceback.extract_stack(), frame[-1] contient une ligne de code source.
Mon exemple est trivial, mais dans le cas général, pour extraire le nom de la fonction à partir du code source, il faut un interpréteur python.

...