J'aimerais pouvoir obtenir le nom d'une variable sous forme de chaîne mais je ne sais pas si Python a autant de capacités d'introspection. Quelque chose comme:
>>> print(my_var.__name__)
'my_var'
Je veux le faire parce que j'ai un tas de variables que je voudrais transformer en dictionnaire comme:
bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict
{'foo': False, 'bar': True}
Mais j'aimerais quelque chose de plus automatique que ça.
Python a locals()
et vars()
, donc je suppose qu'il y a un moyen.
Réponses:
Essayez-vous de faire ça?
Exemple
la source
print('x: ' + x)
un puisse écriremagic_print(x)
et avoir la même sortie sans écrire deux fois le nom de la variable.Comme dit le déroulement, ce n'est pas vraiment quelque chose que vous faites en Python - les variables sont en fait des mappages de noms aux objets.
Cependant , voici une façon d'essayer de le faire:
la source
True
), alors un nom de variable involontaire peut être renvoyé.id(v) == id(a)
au lieu dev is a
? Cela échouera pour les objets liés à plusieurs variables, tels que les entiers, les chaînes et tous les types définis par l'utilisateur de manière similaire.v is a
serait un meilleur choix. Et oui, certainement dangereux compte tenu de tous les pièges potentiels qui pourraient survenir! ;-)J'ai beaucoup voulu faire ça. Ce hack est très similaire à la suggestion de rlotun, mais c'est un one-liner, ce qui est important pour moi:
Python 3+
la source
iteritems()
est remplacé paritems()
spam = 1; blah = 1; blah_name = [ k for k,v in locals().items() if v is blah][0]; print(blah_name)
Sortiesspam
spam = 1, blah = 1; assert spam is blah
. La solution se casse lors de la comparaison des types de données primitifs.Ceci est un hack. Il ne fonctionnera pas sur toutes les distributions d'implémentations Python (en particulier, celles qui n'en ont pas
traceback.extract_stack
.)Notez que ce hack est fragile:
(appeler make_dict sur 2 lignes) ne fonctionnera pas.
Au lieu d'essayer de générer le dict à partir des valeurs
foo
etbar
, il serait beaucoup plus Pythonic de générer le dict à partir des noms de variables de chaîne'foo'
et'bar'
:la source
print("a_very_long_name: {}'.format(a_very_long_name))
qui s'en soucie!Ce n'est pas possible en Python, qui n'a vraiment pas de "variables". Python a des noms et il peut y avoir plusieurs noms pour le même objet.
la source
Je pense que mon problème aidera à illustrer pourquoi cette question est utile, et il peut donner un peu plus d'informations sur la façon d'y répondre. J'ai écrit une petite fonction pour faire une vérification rapide de la tête en ligne sur diverses variables de mon code. Fondamentalement, il répertorie le nom de la variable, le type de données, la taille et d'autres attributs, afin que je puisse rapidement détecter les erreurs que j'ai faites. Le code est simple:
Donc, si vous avez une situation de dictionnaire / liste / tuple compliquée, il serait très utile que l'interprète retourne le nom de variable que vous avez attribué. Par exemple, voici un dictionnaire étrange:
Je ne sais pas si je l'ai mis au bon endroit, mais j'ai pensé que cela pourrait aider. J'espère que oui.
la source
myconnection
pourrait s'agir d'une valeur booléenne à un moment donné, d'un entier à un autre moment et d'une connexion socket à un autre moment de l'exécution du code ??J'ai écrit une petite fonction très utile basée sur la réponse à cette question. Je le mets ici au cas où cela serait utile.
usage:
la source
Je trouve que si vous avez déjà une liste spécifique de valeurs, c'est la manière décrite par @S. Lotts est le meilleur; cependant, la manière décrite ci-dessous fonctionne bien pour obtenir toutes les variables et classes ajoutées dans le code SANS la nécessité de fournir le nom de la variable bien que vous puissiez les spécifier si vous le souhaitez. Le code peut être étendu pour exclure les classes.
Production:
la source
En python 3, c'est facile
cela imprimera:
la source
for v in locals()
.for v in list(locals()):
Python3. Utilisez inspect pour capturer l'espace de noms local appelant, puis utilisez les idées présentées ici. Peut renvoyer plus d'une réponse comme cela a été souligné.
la source
Voici la fonction que j'ai créée pour lire les noms de variables. Il est plus général et peut être utilisé dans différentes applications:
Pour l'utiliser dans la question spécifiée:
la source
En lisant le fil, j'ai vu énormément de frictions. Il est assez facile de donner une mauvaise réponse, puis laissez quelqu'un donner la bonne réponse. Bref, voici ce que j'ai trouvé.
De: [effbot.org] ( http://effbot.org/zone/python-objects.htm#names )
Les noms sont un peu différents - ce ne sont pas vraiment des propriétés de l'objet, et l'objet lui-même ne sait pas comment il s'appelle.
Un objet peut avoir n'importe quel nombre de noms, ou aucun nom du tout.
Les noms vivent dans des espaces de noms (comme un espace de noms de module, un espace de noms d'instance, l'espace de noms local d'une fonction).
Remarque: il dit que l'objet lui-même ne sait pas comment il s'appelle , donc c'était l'indice. Les objets Python ne sont pas auto-référentiels. Ensuite, il dit: Les noms vivent dans des espaces de noms . Nous l'avons dans TCL / TK. Alors peut-être que ma réponse vous aidera (mais cela m'a aidé)
Il y a donc «jj» à la fin de la liste.
Réécrivez le code comme suit:
Ce méchant identifiant de code est le nom de la variable / objet / quel que soit votre nom de pédant.
Tiens voilà. L'adresse mémoire de 'jj' est la même lorsque nous la recherchons directement, que lorsque nous recherchons le dictionnaire dans l'espace de nom global. Je suis sûr que vous pouvez créer une fonction pour ce faire. N'oubliez pas dans quel espace de noms se trouve votre variable / objet / wypci.
QED.
la source
print id(jj)
. Le second recherche simplement le nom et peut être fait plus facilement avecvars()
.Peut-être que j'y pense trop, mais ..
la source
variable = 1 \n [k for k,v in locals().items() if id(variable) == id(v)] \n Out[14]: ['variable']
la source
J'ai téléchargé une solution sur pypi . C'est un module définissant un équivalent de la fonction de C #
nameof
.Il parcourt les instructions de bytecode pour la trame qu'il appelle, obtenant les noms des variables / attributs qui lui sont passés. Les noms se trouvent dans le
.argrepr
desLOAD
instructions ci - dessous le nom de la fonction.la source
J'ai écrit le paquet sorcellerie pour faire ce genre de magie avec robustesse. Tu peux écrire:
la source
La plupart des objets n'ont pas d' attribut __name__ . (Les classes, les fonctions et les modules le font; d'autres types intégrés en ont-ils un?)
Que voulez - vous attendre à
print(my_var.__name__)
autre queprint("my_var")
? Pouvez-vous simplement utiliser la chaîne directement?Vous pouvez "découper" un dicton:
Alternativement:
la source
some_func(var)
, j'ai donc essayé de souligner qu'il n'y en a pas très loinsome_func("var")
, avec dictslice vous permettant d'obtenir le mappage nom-valeur pour plusieurs variables à la fois.Eh bien, j'ai rencontré le même besoin il y a quelques jours et j'ai dû obtenir le nom d' une variable qui pointait vers le objet lui-même.
Et pourquoi était-ce si nécessaire?
En bref, je construisais un plug-in pour Maya . Le plug-in principal a été construit à l'aide de C ++ mais l'interface graphique est dessinée via Python (car elle n'est pas gourmande en processeur). Comme je ne sais pas encore comment
return
multiplier les valeurs du plug-in, sauf la valeur par défautMStatus
, donc pour mettre à jour un dictionnaire en Python, je devais passer le nom de la variable, pointant vers l'objet implémentant l'interface graphique et qui contenait le dictionnaire lui-même, au plug-in, puis utilisez leMGlobal::executePythonCommand()
pour mettre à jour le dictionnaire à partir de la portée globale de Maya .Pour ce faire, ce que j'ai fait était quelque chose comme:
Je sais que ce n'est pas la solution parfaite dans les
globals
nombreuses touches qui pourraient pointer vers le même objet par exemple:et que l'approche n'est pas thread-safe. Corrigez-moi si je me trompe.
Au moins, cette approche a résolu mon problème en obtenant le nom de toute variable dans la portée globale qui pointait vers l' objet lui-même et le transmettait au plug-in, comme argument, pour qu'il l'utilise en interne.
J'ai essayé cela sur
int
(la classe entière primitive) mais le problème est que ces classes primitives ne sont pas contournées (veuillez corriger la terminologie technique utilisée si elle est incorrecte). Vous pouvez réimplémenterint
puis faire,int = foo
mais nea = 3
serez jamais un objetfoo
de la primitive. Pour surmonter cela, vous devez vousa = foo(3)
mettrea.name()
au travail.la source
Avec python 2.7 et plus récent, il existe également une compréhension du dictionnaire qui le rend un peu plus court. Si possible, j'utiliserais getattr à la place eval (eval is evil) comme dans la réponse du haut. Le soi peut être n'importe quel objet qui a le contexte que vous regardez. Il peut s'agir d'un objet ou de locals = locals () etc.
la source
Je travaillais sur un problème similaire. @ S.Lott a dit "Si vous avez la liste des variables, quel est l'intérêt de" découvrir "leurs noms?" Et ma réponse est juste de voir si cela pourrait être fait et si pour une raison quelconque vous voulez trier vos variables par type dans des listes. Donc de toute façon, dans mes recherches, je suis tombé sur ce fil et ma solution est un peu développée et est basée sur la solution @rlotun. Une autre chose, @unutbu a déclaré: "Cette idée a du mérite, mais notez que si deux noms de variable font référence à la même valeur (par exemple, True), alors un nom de variable involontaire peut être renvoyé." Dans cet exercice qui était vrai alors je résignées en utilisant une compréhension de liste semblable à cela pour chaque possibilité:
isClass = [i for i in isClass if i != 'item']
. Sans elle, «item» apparaîtrait dans chaque liste.la source
pi = pie
à votre code, vous obtiendrez une entrée supplémentaire dans votreisFloat
liste. Si vous avez ajoutétuple_1[0]
à votremixedDataTypes
liste, aucun nom ne sera trouvé pour lui malgré le fait que "un" soit dans votre code deux fois (bien que grâce à l'internement de chaînes, ils seront tous les deux des références au même objet).pi
et ene
tant que variables provoquait une sortie indésirable et c'est parce que les deux font partie de lamath
bibliothèque. Pour moi, c'était juste un exercice pour voir si cela pouvait être fait même si le résultat final n'est pas parfait. Dans mon apprentissage de cette langue, passer par les livres ne va que si loin. À mon avis, si vous voulez vraiment apprendre la langue, vous devez jouer "et si" et voir ce que vous proposez.vous pouvez utiliser easydict
un autre exemple:
la source
Sur python3, cette fonction obtiendra le nom le plus externe de la pile:
Il est utile n'importe où sur le code. Traverse la pile inversée à la recherche du premier match.
la source
Bien que ce soit probablement une idée horrible, elle va dans le même sens que la réponse de rlotun, mais elle retournera le résultat correct plus souvent.
Vous l'appelez comme ceci:
la source
devrait obtenir la liste puis revenir
la source
Il ne renverra pas le nom de la variable mais vous pouvez facilement créer un dictionnaire à partir d'une variable globale.
la source
Avec
python-varname
vous pouvez facilement le faire:pip install python-varname
Avertissement: je suis l'auteur de cette bibliothèque python-varname.
la source
de cette façon, obtenez varname pour un peut-être «a» ou «b».
la source