Comment imprimer un nom de variable en python? [dupliquer]
cette question a déjà une réponse ici:
dites que j'ai une variable nommée choice
elle est égale à 2. Comment accéder au nom de la variable? Quelque chose d'équivalent à
In [53]: namestr(choice)
Out[53]: 'choice'
pour une utilisation dans l'élaboration d'un dictionnaire. Il y a un bon moyen de faire ça et je le rate.
EDIT:
la raison de faire ceci est donc. J'exécute quelques trucs d'analyse de données où j'appelle le programme avec plusieurs paramètres que je voudrais modifier, ou ne pas modifier, à l'exécution. J'ai lu dans les paramètres que j'ai utilisé lors de la dernière exécution d'un .fichier de configuration formaté comme
filename
no_sig_resonance.dat
mass_peak
700
choice
1,2,3
lorsqu'on lui demande des valeurs, la précédente utilisé est affiché et une chaîne vide d'entrée utilisera la valeur.
ma question se pose parce que lorsqu'il s'agit d'écrire le dictionnaire, ces valeurs ont été scannées. Si un paramètre est nécessaire je exécuter get_param
qui accède au fichier et trouve le paramètre.
je pense que je vais éviter le problème tous ensemble par la lecture de la . config
fichier une fois et la production d'un dictionnaire. J'ai évité que l'origine pour... des raisons dont je ne me souviens plus. Situation parfaite pour mettre à jour mon code!
8 réponses
si vous insistez, voici une solution basée sur l'inspection.
import inspect, re
def varname(p):
for line in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
m = re.search(r'\bvarname\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)', line)
if m:
return m.group(1)
if __name__ == '__main__':
spam = 42
print varname(spam)
j'espère que cela vous incitera à réévaluer le problème que vous avez et à chercher une autre approche.
pour répondre à votre question initiale:
def namestr(obj, namespace):
return [name for name in namespace if namespace[name] is obj]
exemple:
>>> a = 'some var'
>>> namestr(a, globals())
['a']
comme @rbright a déjà souligné quoi que vous fassiez, il y a probablement de meilleures façons de le faire.
vous ne pouvez pas, car il n'y a pas de variables en Python mais seulement des noms.
par exemple:
> a = [1,2,3]
> b = a
> a is b
True
laquelle de ces deux variables est maintenant la bonne? Il n'y a pas de différence entre a
et b
.
il y a eu une question similaire avant.
Si vous essayez de le faire, cela signifie que vous faites quelque chose de mal. Envisagez plutôt d'utiliser un dict
.
def show_val(vals, name):
print "Name:", name, "val:", vals[name]
vals = {'a': 1, 'b': 2}
show_val(vals, 'b')
sortie:
Name: b val: 2
plutôt que de demander des détails à une solution spécifique, je vous recommande de décrire le problème auquel vous faites face; je pense que vous obtiendrez de meilleures réponses. Je dis cela parce qu'il y a certainement une meilleure façon de faire ce que vous essayez de faire. L'accès aux noms de variables de cette façon n'est généralement pas nécessaire pour résoudre des problèmes dans n'importe quelle langue.
cela dit, tous vos noms de variables sont déjà dans des dictionnaires qui sont accessibles par les fonctions intégrées locaux et globals . Utilisez le bon pour la portée que vous inspectez.
l'un des rares idiomes communs pour inspecter ces dictionnaires est pour l'interpolation facile de chaîne:
>>> first = 'John'
>>> last = 'Doe'
>>> print '%(first)s %(last)s' % globals()
John Doe
ce genre de chose tend à être un peu plus lisible que les alternatives, même si elle nécessite l'inspection des variables par leur nom.
est-ce que quelque chose comme ça va marcher pour vous?
>>> def namestr(**kwargs):
... for k,v in kwargs.items():
... print "%s = %s" % (k, repr(v))
...
>>> namestr(a=1, b=2)
a = 1
b = 2
et dans votre exemple:
>>> choice = {'key': 24; 'data': None}
>>> namestr(choice=choice)
choice = {'data': None, 'key': 24}
>>> printvars(**globals())
__builtins__ = <module '__builtin__' (built-in)>
__name__ = '__main__'
__doc__ = None
namestr = <function namestr at 0xb7d8ec34>
choice = {'data': None, 'key': 24}
pour la question révisée de savoir comment lire dans les paramètres de configuration, je vous recommande fortement de vous épargner du temps et de l'effort et d'utiliser ConfigParser ou (mon outil préféré) ConfigObj .
ils peuvent faire tout ce dont vous avez besoin, ils sont faciles à utiliser, et quelqu'un d'autre s'est déjà inquiété de savoir comment les faire fonctionner correctement!
avec l'évaluation impatiente, les variables se transforment essentiellement en leurs valeurs chaque fois que vous les regardez (pour paraphraser). Cela dit, Python a intégré namespaces . Par exemple, locals() retournera un dictionnaire en faisant correspondre les noms des variables d'une fonction à leurs valeurs, et globals() fera de même pour un module. Ainsi:
for name, value in globals().items():
if value is unknown_variable:
... do something with name
notez que vous n'avez pas besoin d'importer quoi que ce soit pour pouvoir accéder à locals() et globals().
aussi, s'il y a plusieurs alias pour une valeur, itérer à travers un espace de noms ne trouve que le premier.