En Python, sans utiliser le traceback
module, existe-t-il un moyen de déterminer le nom d'une fonction à partir de cette fonction?
Disons que j'ai un module foo avec une barre de fonctions. Lors de l'exécution foo.bar()
, y a-t-il un moyen pour bar de connaître le nom de la barre? Ou mieux encore, son foo.bar
nom?
#foo.py
def bar():
print "my name is", __myname__ # <== how do I calculate this at runtime?
traceback
. Même le temps des réponses et des commentaires ne semble pas le soutenir.Réponses:
Python n'a pas de fonctionnalité pour accéder à la fonction ou à son nom dans la fonction elle-même. Il a été proposé mais rejeté. Si vous ne voulez pas jouer avec la pile vous-même, vous devez utiliser
"bar"
ou enbar.__name__
fonction du contexte.L'avis de rejet donné est:
la source
inspect.currentframe()
est une telle façon.print(inspect.currentframe().f_code.co_name)
la source
[1][3]
pour obtenir le nom de l'appelant.print(inspect.currentframe().f_code.co_name)
ou pour obtenir le nom de l'appelant:print(inspect.currentframe().f_back.f_code.co_name)
. Je pense que cela devrait être plus rapide car vous ne récupérez pas une liste de tous les cadres de pile comme leinspect.stack()
fait.inspect.currentframe().f_back.f_code.co_name
ne fonctionne pas avec une méthode décorée alorsinspect.stack()[0][3]
que ...Il existe plusieurs façons d'obtenir le même résultat:
Notez que les
inspect.stack
appels sont des milliers de fois plus lents que les alternatives:la source
inspect.currentframe()
semble un bon compromis entre le temps d'exécution et l'utilisation de membres privés0.100 usec
ou0.199 usec
mais de toute façon - des centaines de fois plus rapide que les options 1 et 2, comparable à l'option 4 (bien qu'Antony Hatchkins ait trouvé l'option 3 trois fois plus rapide que l'option 4).sys._getframe().f_code.co_name
overinspect.currentframe().f_code.co_name
simplement parce que j'ai déjà importé lesys
module. Est-ce une décision raisonnable? (considérant que les vitesses semblent assez similaires)Vous pouvez obtenir le nom avec lequel il a été défini en utilisant l'approche indiquée par @Andreas Jung , mais ce n'est peut-être pas le nom avec lequel la fonction a été appelée:
Que cette distinction soit importante pour vous ou non, je ne peux pas le dire.
la source
.func_name
. Il faut se rappeler que les noms de classe et les noms de fonction en Python sont une chose et que les variables qui s'y réfèrent en sont une autre.Foo2()
être imprimerFoo
. Par exemple:Foo2 = function_dict['Foo']; Foo2()
. Dans ce cas, Foo2 est un pointeur de fonction pour peut-être un analyseur de ligne de commande.Je voulais une chose très similaire parce que je voulais mettre le nom de la fonction dans une chaîne de journal qui allait à plusieurs endroits dans mon code. Ce n'est probablement pas la meilleure façon de le faire, mais voici un moyen d'obtenir le nom de la fonction actuelle.
la source
f
cadre et leco
code. Je ne l'utilise pas tellement, tant mieux si je l'enregistre dans un extrait :-)Je garde cet utilitaire à portée de main:
Usage:
la source
Je suppose que
inspect
c'est la meilleure façon de le faire. Par exemple:la source
J'ai trouvé un wrapper qui écrira le nom de la fonction
Cela imprimera
la source
my_funky_name.__name__
. Vous pouvez passer le nom func .____ dans la fonction en tant que nouveau paramètre. func (* args, ** kwargs, my_name = func .__ name__). Pour obtenir le nom de votre décorateur à l'intérieur de votre fonction, je pense que cela nécessiterait d'inspecter. Mais obtenir le nom de la fonction contrôlant ma fonction au sein de ma fonction de course ... eh bien, ça sonne juste comme le début d'un beau mème :)Ceci est en fait dérivé des autres réponses à la question.
Voici mon point de vue:
L'avantage probable de cette version par rapport à l'inspection.stack () est qu'elle devrait être des milliers de fois plus rapide [voir la publication d'Alex Melihoff et les délais concernant l'utilisation de sys._getframe () par rapport à l'utilisation d'inspect.stack ()].
la source
print(inspect.stack()[0].function)
semble fonctionner aussi (Python 3.5).la source
Voici une approche évolutive.
La combinaison des suggestions de @ CamHart et @ Yuval avec la réponse acceptée de @ RoshOxymoron a l'avantage d'éviter:
_hidden
et méthodes potentiellement obsolètesJe pense donc que cela fonctionne bien avec les futures versions de python (testées sur 2.7.3 et 3.3.2):
la source
Tester:
Production:
la source
Je ne sais pas pourquoi les gens compliquent les choses:
la source
Dans IDE, les sorties de code
la source
Vous pouvez utiliser un décorateur:
la source
__name__
attribut d'une fonction. L'utilisation nécessite de connaître la chose que vous essayez d'obtenir, ce qui ne me semble pas très utile dans les cas simples où les fonctions ne sont pas définies à la volée.Je fais ma propre approche utilisée pour appeler super avec sécurité dans un scénario d'héritage multiple (je mets tout le code)
exemple d'utilisation:
le tester:
production:
À l'intérieur de chaque méthode décorée @with_name, vous avez accès à self .__ fname__ comme nom de fonction actuel.
la source
J'ai récemment essayé d'utiliser les réponses ci-dessus pour accéder à la docstring d'une fonction à partir du contexte de cette fonction, mais comme les questions ci-dessus ne renvoyaient que la chaîne de nom, cela n'a pas fonctionné.
Heureusement, j'ai trouvé une solution simple. Si comme moi, vous voulez vous référer à la fonction plutôt que simplement obtenir la chaîne représentant le nom, vous pouvez appliquer eval () à la chaîne du nom de la fonction.
la source
Je suggère de ne pas compter sur des éléments de pile. Si quelqu'un utilise votre code dans différents contextes (interprète python par exemple), votre pile changera et cassera votre index ([0] [3]).
Je vous suggère quelque chose comme ça:
la source
C'est assez facile à réaliser avec un décorateur.
la source