Python: charger des variables dans un dict dans un espace de noms

Je veux utiliser un tas de variables locales définies dans une fonction, en dehors de la fonction. Donc, je passe x=locals() dans la valeur de retour.

Comment puis-je charger toutes les variables définies dans ce dictionnaire dans l'espace de noms en dehors de la fonction, de sorte qu'au lieu d'accéder à la valeur en utilisant x['variable'], je pourrais simplement utiliser variable.

47
demandé sur dreftymac 2010-04-08 06:50:31

6 réponses

Considérons l'alternative Bunch:

class Bunch(object):
  def __init__(self, adict):
    self.__dict__.update(adict)

Donc, si vous avez un dictionnaire d et que vous voulez accéder (lire) à ses valeurs avec la syntaxe x.foo au lieu du maladroit d['foo'], faites simplement

x = Bunch(d)

Cela fonctionne à la fois à l'intérieur et à l'extérieur des fonctions-et c'est énormément plus propre et plus sûr que d'injecter d dans globals()! Rappelez-vous la dernière ligne du Zen de Python...:

>>> import this
The Zen of Python, by Tim Peters
   ...
Namespaces are one honking great idea -- let's do more of those!
78
répondu Alex Martelli 2010-04-08 03:40:50

C'est un cas parfaitement valide pour importer des variables dans un espace local dans un autre espace local aussi longtemps que on est conscient de ce qu'il/elle fait. J'ai vu plusieurs fois utilisé de façons utiles. Juste besoin de faire attention à ne pas polluer l'espace global commun.

Vous pouvez faire ce qui suit:

adict = { 'x' : 'I am x', 'y' : ' I am y' }
locals().update(adict)
blah(x)
blah(y)
15
répondu Thava 2013-03-17 15:59:56

L'importation de variables dans un espace de noms local est un problème valide et souvent utilisé dans les frameworks de modèles.

Renvoie toutes les variables locales d'une fonction:

return locals()

Puis importer comme suit:

r = fce()
for key in r.keys():
   exec(key + " = r['" + key + "']")
7
répondu Radek 2011-02-05 10:20:25

, Plutôt que de créer votre propre objet, vous pouvez utiliser argparse.Namespace:

from argparse import Namespace
ns = Namespace(**mydict)

Pour faire l'inverse:

mydict = vars(ns)
2
répondu orodbhen 2018-05-01 14:54:58

Il y a toujours cette option, Je ne sais pas que c'est la meilleure méthode, mais ça marche vraiment. En supposant type (x) = dict

for key, val in x.items():  # unpack the keys from the dictionary to individual variables
    exec (key + '=val')
0
répondu SBFRF 2016-09-16 20:35:15

Utilisé l'extrait suivant (PY2) pour créer un espace de noms récursif à partir de mes configurations dict (yaml):

class NameSpace(object):
    def __setattr__(self, key, value):
        raise AttributeError('Please don\'t modify config dict')


def dump_to_namespace(ns, d):
    for k, v in d.iteritems():
        if isinstance(v, dict):
            leaf_ns = NameSpace()
            ns.__dict__[k] = leaf_ns
            dump_to_namespace(leaf_ns, v)
        else:
            ns.__dict__[k] = v

config = NameSpace()
dump_to_namespace(config, config_dict)
0
répondu madzohan 2018-07-10 11:44:27