web-dev-qa-db-fra.com

Python: charge les variables d'un dict dans un espace de noms

Je veux utiliser un groupe de variables locales définies dans une fonction, en dehors de la fonction. Je passe donc 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 à l'aide de x['variable'], je pourrais simplement utiliser variable.

50
dzhelil

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 plus gros 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!
80
Alex Martelli

C’est un cas parfaitement valable pour importer des variables inun espace local dans un autre espace local aussi longtemps queone est au courant de ce qu’il/elle est en train de faire . façons . Il faut juste faire attention à ne pas polluer l’espace mondial commun.

Vous pouvez faire ce qui suit:

adict = { 'x' : 'I am x', 'y' : ' I am y' }
locals().update(adict)
blah(x)
blah(y)
15
Thava

Importer des variables dans un espace de noms local est un problème valide et est souvent utilisé dans les frameworks de templates.

Renvoie toutes les variables locales d'une fonction:

return locals()

Importez ensuite comme suit:

r = fce()
for key in r.keys():
   exec(key + " = r['" + key + "']")
7
Radek

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)
7
orodbhen

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

for key, val in x.items():  # unpack the keys from the dictionary to individual variables
    exec (key + '=val')
0
SBFRF

Utilisé après l'extrait de code (PY2) pour créer un espace de nom récursif à partir de mes configs 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
madzohan