Disons que j'ai une variable nommée choice
elle est égale à 2. Comment pourrais-je accéder au nom de la variable? Quelque chose d'équivalent à
In [53]: namestr(choice)
Out[53]: 'choice'
à utiliser pour créer un dictionnaire. Il y a un bon moyen de le faire et ça me manque juste.
MODIFIER:
La raison en est ainsi. J'exécute des trucs d'analyse de données où j'appelle le programme avec plusieurs paramètres que je voudrais Tweak, ou pas Tweak, au moment de l'exécution. J'ai lu les paramètres que j'ai utilisés lors de la dernière exécution à partir d'un fichier .config formaté comme
filename
no_sig_resonance.dat
mass_peak
700
choice
1,2,3
Lorsque vous êtes invité à entrer des valeurs, la valeur précédemment utilisée s'affiche et une entrée de chaîne vide utilise la valeur précédemment utilisée.
Ma question vient du fait que lorsqu'il s'agit d'écrire le dictionnaire, ces valeurs ont été numérisées. Si un paramètre est nécessaire, je lance get_param
qui accède au fichier et trouve le paramètre.
Je pense que j'éviterai le problème tous ensemble en lisant une fois le fichier .config
et en produisant un dictionnaire à partir de cela. J'ai évité cela à l'origine pour ... des raisons dont je ne me souviens plus. Situation parfaite pour mettre à jour mon code!
Si vous insistez, voici une horrible 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 __== '__main__':
spam = 42
print varname(spam)
J'espère que cela vous inspirera à réévaluer le problème que vous avez et à chercher une autre approche.
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 l'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 dans Python mais seulement des noms.
Par exemple:
> a = [1,2,3]
> b = a
> a is b
True
Laquelle de ces deux est maintenant la bonne variable? Il n'y a pas de différence entre a
et b
.
Il y a eu une question similaire avant.
Si vous essayez de faire cela, cela signifie que vous faites quelque chose de mal. Pensez à utiliser un dict
à la place.
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 sur une solution spécifique, je recommande de décrire le problème auquel vous êtes confronté; Je pense que vous obtiendrez de meilleures réponses. Je dis cela car il y a presque certainement une meilleure façon de faire tout ce que vous essayez de faire. L'accès aux noms de variables de cette manière 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 accessibles via les fonctions intégrées locals et globals . Utilisez la bonne pour la portée que vous inspectez.
L'un des rares idiomes courants pour inspecter ces dictionnaires est l'interpolation de chaînes facile:
>>> first = 'John'
>>> last = 'Doe'
>>> print '%(first)s %(last)s' % globals()
John Doe
Ce genre de chose a tendance à être un peu plus lisible que les alternatives même si cela nécessite d'inspecter les variables par leur nom.
Pour la question révisée de la lecture des paramètres de configuration, je vous recommande fortement de vous épargner du temps et des efforts 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à demandé comment les faire fonctionner correctement!
Est-ce que quelque chose comme ça fonctionnera 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)>
__= '__main__'
__doc__ = None
namestr = <function namestr at 0xb7d8ec34>
choice = {'data': None, 'key': 24}
Avec une évaluation enthousiaste, les variables deviennent essentiellement leurs valeurs à chaque fois que vous les regardez (pour paraphraser). Cela dit, Python a intégré espaces de noms . Par exemple, locals () retournera un dictionnaire mappant les noms des variables d'une fonction à leurs valeurs et globals ( ) fait 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 aux sections locales () et globales ().
En outre, s'il existe plusieurs alias pour une valeur, l'itération dans un espace de noms ne trouve que le premier.