Python: загрузка переменных в dict в пространство имен - PullRequest
52 голосов
/ 08 апреля 2010

Я хочу использовать кучу локальных переменных, определенных в функции, вне функции. Так что я передаю x=locals() в возвращаемое значение.

Как загрузить все переменные, определенные в этом словаре, в пространство имен вне функции, чтобы вместо доступа к значению с помощью x['variable'] я мог просто использовать variable.

Ответы [ 6 ]

83 голосов
/ 08 апреля 2010

Рассмотрим альтернативу Bunch:

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

, поэтому, если у вас есть словарь d и вы хотите получить доступ (прочитать) его значения с синтаксисом x.foo вместо неуклюжего d['foo']просто сделайте

x = Bunch(d)

, это работает как внутри, так и снаружи - и это чрезвычайно чище и безопаснее, чем введение d в globals()!Помните последнюю строчку из дзен Python ...:

>>> import this
The Zen of Python, by Tim Peters
   ...
Namespaces are one honking great idea -- let's do more of those!
16 голосов
/ 25 октября 2010

Это вполне допустимый случай для импорта переменных в одно локальное пространство в другое локальное пространство до тех пор, пока каждый знает о том, что он / она делает. Я видел, как такой код много раз использовался полезными способами. Просто нужно быть осторожным, чтобы не загрязнять общее глобальное пространство.

Вы можете сделать следующее:

adict = { 'x' : 'I am x', 'y' : ' I am y' }
locals().update(adict)
blah(x)
blah(y)
13 голосов
/ 01 мая 2018

Вместо того, чтобы создавать свой собственный объект, вы можете использовать argparse.Namespace:

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

Чтобы сделать обратное:

mydict = vars(ns)
7 голосов
/ 05 февраля 2011

Импорт переменных в локальное пространство имен является допустимой проблемой и часто используется в шаблонных средах.

Возвращает все локальные переменные из функции:

return locals()

Затем импортируйте следующим образом:

r = fce()
for key in r.keys():
   exec(key + " = r['" + key + "']")
0 голосов
/ 10 июля 2018

Использовал следующий фрагмент (PY2) для создания рекурсивного пространства имен из моих настроек 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 голосов
/ 16 сентября 2016

Всегда есть эта опция, я не знаю, что это лучший метод, но он действительно работает. Предполагая, что тип (x) = dict

for key, val in x.items():  # unpack the keys from the dictionary to individual variables
    exec (key + '=val')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...