Python: загружать переменные в dict в пространство имен
Я хочу использовать кучу локальных переменных, определенных в функции, вне функции. Поэтому я передаю x=locals()
в возвращаемом значении.
Как я могу загрузить все переменные, определенные в этом словаре, в пространство имен вне функции, так что вместо доступа к значению с помощью x['variable']
я мог бы просто использовать variable
.
Ответы
Ответ 1
Рассмотрим альтернативу Bunch
:
class Bunch(object):
def __init__(self, adict):
self.__dict__.update(adict)
поэтому, если у вас есть словарь d
и вы хотите получить доступ (прочитайте) его значения с помощью синтаксиса x.foo
вместо clumier d['foo']
, просто сделайте
x = Bunch(d)
это работает как внутри, так и снаружи функций - и это чрезвычайно чище и безопаснее, чем впрыскивание d
в globals()
! Помните последнюю строку из Zen of Python...:
>>> import this
The Zen of Python, by Tim Peters
...
Namespaces are one honking great idea -- let do more of those!
Ответ 2
Вместо того, чтобы создавать свой собственный объект, вы можете использовать argparse.Namespace
:
from argparse import Namespace
ns = Namespace(**mydict)
Чтобы сделать обратное:
mydict = vars(ns)
Ответ 3
Это вполне допустимый случай для импорта переменных в
одно локальное пространство в другое локальное пространство, пока
кто-то знает, что он делает.
Я видел, что такой код много раз использовался полезными способами.
Просто нужно быть осторожным, чтобы не загрязнять общее глобальное пространство.
Вы можете сделать следующее:
adict = { 'x' : 'I am x', 'y' : ' I am y' }
locals().update(adict)
blah(x)
blah(y)
Ответ 4
Импорт переменных в локальное пространство имен является допустимой проблемой и часто используется в шаблонах шаблонов.
Вернуть все локальные переменные из функции:
return locals()
Затем импортируйте следующим образом:
r = fce()
for key in r.keys():
exec(key + " = r['" + key + "']")
Ответ 5
Всегда всегда этот вариант, я не знаю, что это лучший метод, но он уверен, что он работает. Предполагая тип (x) = dict
for key, val in x.items(): # unpack the keys from the dictionary to individual variables
exec (key + '=val')
Ответ 6
Использовал следующий фрагмент (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)