Comment puis-je obtenir le nom d'un objet en Python?
Est-il possible d'obtenir le nom d'un objet en Python? Par exemple:
my_list = [x, y, z] # x, y, z have been previously defined
for bla in my_list:
print "handling object ", name(bla) # <--- what would go instead of `name`?
# do something to bla
Edit: contexte:
Ce que je suis en train de faire est de créer une liste des fonctions que je peux préciser par la ligne de commande.
J'ai:
def fun1:
pass
def fun2
pass
def fun3:
pass
fun_dict = {'fun1': fun1,
'fun2': fun2,
'fun3': fun3}
- Je obtenir le nom de la fonction à partir de la ligne de commande et je tiens à appeler la fonction correspondante:
func_name = parse_commandline()
fun_dict[func_name]()
Et la raison pour laquelle je veux avoir le nom de la fonction est parce que je veux créer fun_dict
sans écrire les noms des fonctions deux fois, puisque cela semble être une bonne façon de créer des bugs. Ce que je veux faire est:
fun_list = [fun1, fun2, fun3] # and I'll add more as the need arises
fun_dict = {}
[fun_dict[name(t) = t for t in fun_list] # <-- this is where I need the name function
De cette façon, j'ai seulement besoin d'écrire les noms de fonction une fois.
- Ce qui devrait qui de retour de la fonction dans ce cas?
- Comme d'habitude, je vais vous demander de nous dire quel est le problème que vous essayez de résoudre.
- meta.stackexchange.com/questions/18584/...
- est-ce mieux?
- Oui. Parce que les fonctions ont un
__name__
attribut. - St comme
def getname(obj): try: name = obj.__name__ except AttributeError as e: name = re.match("^'(.*)'", str(e)).group(1) return name
(ou linéaire de la recherche pour """ au lieu dere
utilisation du module) ? - Près de dix ans et aucune explication de ce que vous étiez en train de faire? Déclarer certaines fonctions globales? (mais pourquoi pas un corps de fonction? ou pourquoi ne pas les emballer dans votre propre paquet et de l'importer?) Et qu'est-ce que le code d'essayer de faire: avoir Python analyser un (Windows/Unix) de ligne de commande pour ces noms, puis d'appeler le correspondant Python (global) de la fonction? Et je ne vois pas pourquoi ils devaient absolument être global. Je pense que le but de votre question était plutôt "Comment Python résoudre fonction/méthode des références?"
Vous devez vous connecter pour publier un commentaire.
Objets n'ont pas forcément les noms en python, donc vous ne pouvez pas obtenir le nom.
Il n'est pas inhabituel pour les objets ont une
__name__
attribut dans ces cas qu'ils ont un nom, mais ce n'est pas une partie de standard de python, et pour la plupart construites dans les types n'en ont pas.Lorsque vous créez une variable, comme l'x, y, z ci-dessus, puis ces noms agissent simplement comme des "pointeurs" ou "références" aux objets. L'objet lui-même ne sait pas ce nom que vous utilisez pour elle, et vous ne pouvez pas facilement (si) les noms de toutes les références à cet objet.
Mise à jour: Cependant, les fonctions ont un
__name__
(sauf s'ils sont lambdas) donc, dans ce cas, vous pouvez le faire:id(obj) == id(xx)
is
.id(666)
. Mais ce n'était pas l'utilisateur déclaré.foo = [MyClass()]
, nous avons déclaré un objet et a choisi de ne pas le stocker. Nous pourrions avoir capturé il si nous le voulions. Donc, le raffinage, l'OP est question de l'utilisateur déclare des objets dont la référence ne pouvait pas avoir été capturé. Toujours en attente de vos exemples spécifiques de non-alias non-propriétédeepcopy objet avec plus d'un nom. Arrêter d'être injurieux, btw. Vous êtes à violer les conditions d'utilisation.Ce n'est pas vraiment possible, car il pourrait y avoir plusieurs variables qui ont la même valeur ou de valeur ne peut avoir aucune variable ou une valeur peut avoir la même valeur qu'une variable que par hasard.
Si vous voulez vraiment le faire, vous pouvez utiliser
Cependant, il serait mieux si vous itérer sur les noms en premier lieu:
[a,b,c]
vous avez une liste d'objets, les variables elles-mêmes ne sont pas pertinents à la liste résultante est créé.Si vous êtes à la recherche pour obtenir les noms des fonctions ou des lambdas ou d'autres fonctions comme des objets qui sont définis dans l'interpréteur, vous pouvez utiliser
dill.source.getname
deaneth
. Il semble pour le__name__
méthode, mais dans certains cas, il connaît d'autres de la magie pour savoir comment trouver le nom... ou un nom de l'objet. Je ne veux pas entrer dans une polémique au sujet de trouver le seul vrai nom pour un objet python, quoi que cela signifie.Ce one-liner œuvres, pour tous les types d'objets, aussi longtemps qu'ils sont en
globals()
dict, qu'elles doivent être:ou, de manière équivalente:
not objname.startwith('_')
. J'ai été d'obtenir beaucoup de résultats, comme id_26 ou __loader__ manifestement erronée. Bien sûr, si vous déclarez des noms commençant par un caractère de soulignement, alors vous pouvez filtrer __ à la place. J'ai posté une réponse, y compris ce genre de choses.Voici une autre façon de penser. Supposons qu'il y ait un
name()
fonction qui a retourné le nom de son argument. Étant donné le code suivant:Ce qui devrait
name(e[2])
de retour, et pourquoi?Comme d'autres l'ont mentionné, c'est vraiment une question délicate. Des Solutions de ce ne sont pas de "one size fits all", pas même à distance. La difficulté (ou de facilité) va vraiment dépendre de votre situation.
Je suis venu à ce problème à plusieurs reprises, mais plus récemment, lors de la création d'une fonction de débogage. Je voulais la fonction de prendre certains objets inconnus comme arguments et d'imprimer leurs déclaré des noms et des matières. Obtenir le contenu est facile bien sûr, mais la déclaration de nom est une autre histoire.
Ce qui suit est une partie de ce que je suis venu avec.
Retourner le nom de la fonction
Déterminer le nom d'une fonction est vraiment facile, car il a la __nom__ attribut contenant la fonction déclarée de nom.
Un exemple, si vous créez la fonction
def test_function(): pass
, puiscopy_function = test_function
, puisname_of_function(copy_function)
, il sera de retour test_function.De retour correspondante premier nom de l'objet
Vérifier si l'objet a un __nom__ attribut et le retourner si donc (les fonctions déclarées uniquement). Notez que vous pouvez supprimer ce test que le nom sera toujours dans
globals()
.Comparer la valeur de arg avec les valeurs d'éléments dans
globals()
et de retourner le nom du premier match. Notez que je suis en filtrant les noms commençant par '_'.Le résultat sera composé du nom du premier objet correspondant, autrement Aucun.
Retour de tous les noms d'objet
globals()
et de stocker des noms dans une liste. Notez que je suis en filtrant les noms commençant par '_'.Le résultat sera constitué d'une liste (pour des correspondances multiples), une chaîne de caractères (un seul match), sinon Aucun. Bien sûr, vous devez ajuster ce comportement en tant que de besoin.
Noter que, bien que, comme l'a noté, les objets en général ne sont pas et ne peuvent pas savoir ce que les variables sont liés à eux, les fonctions définies avec
def
ont des noms dans le__name__
attribut (le nom utilisé dansdef
). Aussi, si les fonctions sont définies dans le même module (comme dans votre exemple), alorsglobals()
contiendra un sur-ensemble du dictionnaire que vous souhaitez.À cette fin, vous avez une magnifique
getattr
fonction, qui vous permet d'obtenir un objet par un nom connu. Donc, vous pourriez le faire par exemple:funcs.py:
main.py:
funcs
. bien sûr, vous devriez filtrer toutes les entrées de l'utilisateur, c'est la règle correcte même en Python, mais vous pouvez fairefuncs
à être propre et à un module d'interface, qui vous devriez probablement faire de toute façon.getattr
permet également de secours par défaut des valeurs.Utiliser un reverse dict.
L'inverse dict mappe chaque référence de fonction pour le nom exact que vous avez donné dans fun_dict, qui peut ou peut ne pas être le nom que vous avez utilisé lorsque vous avez défini la fonction. Et, cette technique se généralise à d'autres objets, y compris des entiers.
Pour plus de plaisir et de folie, vous pouvez stocker l'avant et inverse les valeurs dans la même dict. Je ne le ferais pas, si vous étiez la cartographie des chaînes de chaînes, mais si vous faites quelque chose comme une fonction des références et des chaînes, il n'est pas trop fou.
Les noms de variables peuvent être trouvés dans la globals() et les habitants() dicts. Mais ils ne vous donnera pas ce que vous cherchez ci-dessus. "bla" contenant la valeur de chaque élément de my_list, pas la variable.
Généralement lorsque vous êtes désireux de faire quelque chose comme cela, vous créez une classe afin de conserver l'ensemble de ces fonctions et de les nommer avec claire préfixe
cmd_
ou similaires. Vous prenez alors la chaîne à partir de la commande, et essayer d'obtenir cet attribut de la classe avec lecmd_
le préfixe pour elle. Maintenant vous avez seulement besoin d'ajouter une nouvelle fonction/méthode à la classe, et il est disponible pour votre interlocuteur. Et vous pouvez utiliser la doc chaînes pour créer automatiquement le texte d'aide.Comme décrit dans les autres réponses, vous pouvez être en mesure de faire la même démarche avec
globals()
et régulier des fonctions de votre module pour mieux correspondre à ce que vous avez demandé.Quelque chose comme ceci:
Je suis tombé sur cette page tout en me demandant la même question.
Comme d'autres l'ont noté, il est assez simple à saisir simplement la
__name__
attribut à partir d'une fonction afin de déterminer le nom de la fonction. Elle est légèrement plus compliqué avec des objets qui n'ont pas une façon saine de déterminer__name__
, c'est à dire de la base/les objets primitifs comme basestring cas, ints, aspire, etc.Longue histoire courte, vous pourriez probablement utiliser les inspecter module pour faire une supposition éclairée au sujet de laquelle il s'agit, mais vous devez probablement savoir ce cadre, vous travaillez au sein d'/traverse le bas de la pile à trouver la bonne. Mais je déteste imaginer la façon dont beaucoup de plaisir ce serait d'essayer de traiter avec eval/exec ed code.
whats_my_name_again.py:
Vous définissez un
class
et ajouter l'Unicode privé de la fonction insérer leclass
commeBien sûr, vous devez ajouter de la variable
self.name
qui est le nom de l'objet.Voici ma réponse, je suis également en utilisant globals().les éléments()
J'ai ajouté except_word parce que je veux filtrer quelques mot utilisé dans la boucle for.
Si vous n'avez pas l'ajouter, le mot-clé dans la boucle for peut confondre cette fonction, parfois le mot clé comme "each_item" dans le cas suivant peut afficher dans le résultat de la fonction, dépend de ce que vous avez fait de votre boucle.
par exemple.
par exemple.
Espère que cela peut vous aider.
Python a des noms qui sont mappés aux objets dans un hashmap appelé un espace de noms. À tout instant dans le temps, un nom se réfère toujours à un seul objet, mais un seul objet peut être désigné par un nombre quelconque de noms. Donné un nom, il est très efficace pour la table de hachage pour rechercher le seul objet dont le nom se réfère. Toutefois, étant donné une objet, qui, comme mentionné peut être désigné par plusieurs noms, il n'existe pas de moyen efficace pour rechercher les noms qui se réfèrent à elle. Ce que vous avez à faire est de parcourir tous les noms dans l'espace de noms et de vérifier chacun d'eux individuellement et voir si elle correspond à votre objet donné. Cela peut facilement être fait avec une compréhension de liste:
Cela permettra d'évaluer à une liste de chaînes de caractères containting les noms de tous les "variables" qui sont actuellement mappée à l'objet
myobj
.Bien sûr
locals()
peut être substitué avec toutdict
que vous souhaitez rechercher pour les noms qui renvoient à un objet donné. Évidemment, cette recherche peut être lent pour de très grands espaces de noms, parce qu'ils doivent être parcourus dans leur intégralité.