web-dev-qa-db-de.com

Python: Lädt Variablen eines Diktiers in den Namespace

Ich möchte eine Reihe von lokalen Variablen verwenden, die in einer Funktion außerhalb der Funktion definiert sind. Ich übergeben also x=locals() im Rückgabewert. 

Wie kann ich alle in diesem Wörterbuch definierten Variablen außerhalb der Funktion in den Namespace laden, sodass ich anstelle von x['variable'] auf den Wert einfach variable verwenden kann.

50
dzhelil

Betrachten Sie die Bunch-Alternative:

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

wenn Sie also ein Wörterbuch d haben und auf seine Werte mit der Syntax x.foo anstelle des unbeholfenen d['foo'] zugreifen wollen (lesen), tun Sie dies einfach

x = Bunch(d)

dies funktioniert sowohl innerhalb als auch außerhalb von Funktionen - und es ist enorm sauberer und sicherer, als d in globals() zu injizieren! Erinnere dich an die letzte Zeile aus dem Zen of 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

Dies ist durchaus zutreffend, um Variablen ineinem lokalen Raum in einen anderen lokalen Raum zu importieren, solangeone sich dessen bewusst ist, was er/sie tut Wege ... Sie müssen nur vorsichtig sein, um den gemeinsamen globalen Raum nicht zu verschmutzen.

Sie können Folgendes tun:

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

Das Importieren von Variablen in einen lokalen Namespace ist ein gültiges Problem und wird häufig beim Schablonieren von Frameworks verwendet.

Gibt alle lokalen Variablen aus einer Funktion zurück:

return locals()

Dann importieren Sie wie folgt:

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

Anstatt Ihr eigenes Objekt zu erstellen, können Sie argparse.Namespace verwenden:

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

Um die Umkehrung auszuführen:

mydict = vars(ns)
7
orodbhen

Es gibt immer diese Option, ich weiß nicht, dass es die beste Methode ist, aber es funktioniert sicher. Angenommen, Typ (x) = Dikt

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

Verwendet folgendes Snippet (PY2), um aus meinen Dict (yaml) -Konfigurationen rekursiven Namespace zu erstellen:

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