Как сделать элементы словаря Python доступными через точку "."?
Например, вместо того, чтобы писать mydict['val']
, я хотел бы написать mydict.val
.
Также я хотел бы получить доступ к вложенным диктовкам таким образом. Например
mydict.mydict2.val
будет относиться к
mydict = { 'mydict2': { 'val': ... } }
python
dictionary
syntax
nested
bodacydo
источник
источник
d[a][b][c]
заменяетd[a, b, c]
.{"my.key":"value"}
? Или когда ключом является ключевое слово, например «от»? Я рассматривал это пару раз, и это больше проблем и устранения неполадок, чем предполагаемых преимуществ.Ответы:
Вы можете сделать это, используя этот класс, который я только что сделал. С этим классом вы можете использовать
Map
объект как другой словарь (включая сериализацию json) или с точечной нотацией. Я надеюсь помочь вам:Примеры использования:
источник
.iteritems()
до.items()
AttributeError
если атрибут не существует. Вместо этого он вернетсяNone
.self.update(*args,**kwargs)
. Также вы можете добавить__missing__(self,key): value=self[key]= type(self)(); return value
. Затем вы можете добавить недостающие записи, используя точечную запись. Если вы хотите, чтобы его можно было выбрать, вы можете добавить__getstate__
и__setstate__
hasattr(Map, 'anystring') is true. which means the hasattr would always return True due to overriding
__getattr__`Я всегда держал это в файле утилит. Вы также можете использовать его как миксин на своих собственных занятиях.
источник
d = {'foo': {'bar': 'baz'}}; d = dotdict(d); d.foo.bar
выдает ошибку атрибута, ноd.foo
работает нормально.python class DotDict(dict): """dot.notation access to dictionary attributes""" def __getattr__(*args): val = dict.get(*args) return DotDict(val) if type(val) is dict else val __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__
get
это действительно плохая идея, поскольку она будет возвращатьсяNone
вместо того, чтобыустанавливать
dotmap
черезpip
Он делает все, что вы хотите, и подклассы
dict
, поэтому он работает как обычный словарь:Кроме того, вы можете преобразовать его в и из
dict
объектов:Это означает, что если что-то, к чему вы хотите получить доступ, уже находится в
dict
форме, вы можете превратить его вDotMap
простой для доступа:Наконец, он автоматически создает нового ребенка
DotMap
экземпляры, чтобы вы могли делать такие вещи:Сравнение с кучей
Полное раскрытие: я создатель DotMap . Я создал это, потому что
Bunch
не хватало этих возможностейDotMap
создание элементов, которое экономит время и делает код чище, когда у вас много иерархииdict
и рекурсивное преобразование всех дочернихdict
экземпляров вDotMap
источник
{"test.foo": "bar"}
можно получить доступ черезmymap.test.foo
Это было бы фантастически. Потребуется некоторое восстановление, чтобы преобразовать плоскую карту в глубокую карту, а затем применить к ней DotMap, но это того стоит!DotMap
автозаполнения работает лучше всего. Я использую Sublime Text, который автозаполняет ранее набранные ключевые слова.**kwargs
илиc = {**a, **b}
. На самом деле, он не работает тихо, он ведет себя как пустой словарь при извлечении.m = DotMap(); m.a = 2; m.b = 3; print('{a} {b}'.format(**m));
и получил ожидаемое2 3
. Если у вас есть проверенный случай, который работает,dict()
но не работаетDotMap()
, отправьте код на вкладку «Проблемы» в GitHub.Получите из dict и и осуществите
__getattr__
и__setattr__
.Или вы можете использовать Bunch, который очень похож.
Я не думаю, что это возможно, чтобы monkeypatch встроенный класс dict.
источник
У Fabric действительно хорошая минимальная реализация . Расширяя это, чтобы разрешить вложенный доступ, мы можем использовать a
defaultdict
, и результат будет выглядеть примерно так:Используйте это следующим образом:
Это конкретизирует немного на ответ Кугель о «проистекают из Dict и и осуществлять
__getattr__
и__setattr__
». Теперь ты знаешь как!источник
dotdict
которая позволяетdict
рекурсивно преобразовывать существующий объект: gist.github.com/miku/…Я попробовал это:
ты
__getattribute__
тоже можешь попробоватьсделайте каждый dict типом dotdict достаточно хорошо, если вы хотите инициировать это из многослойного dict, попробуйте также реализовать
__init__
.источник
def docdict(name):
перед ней и затем `if isinstance (name, dict): return DotDict (name) возвращаемое имя`class dotdict(dict): def __getattr__(self, name): if name not in self: return None elif type(self[name]) is dict: return JsonDot(self[name]) else: return self[name]
Не. Доступ к атрибутам и индексация - это разные вещи в Python, и вам не следует, чтобы они выполняли то же самое. Создайте класс (возможно, созданный
namedtuple
), если у вас есть что-то, что должно иметь доступные атрибуты, и используйте[]
нотацию, чтобы получить элемент из указания.источник
.
вместо[]
доступа к сложным структурам данных в шаблонах Mako.Если вы хотите выбрать измененный словарь, вам нужно добавить несколько методов состояния к ответам выше:
источник
__getattr__ = dict.get
Основываясь на ответе Кугеля и принимая во внимание слова предостережения Майка Грэма, что, если мы сделаем обертку?
источник
Используйте
SimpleNamespace
:источник
Мне нравится Munch, и он дает множество удобных опций поверх доступа к точке.
источник
Недавно я наткнулся на библиотеку « Box », которая делает то же самое.
Команда установки:
pip install python-box
Пример:
Я обнаружил, что он более эффективен, чем другие существующие библиотеки, такие как dotmap, которые генерируют ошибку рекурсии Python, когда у вас большие вложенные запросы.
ссылка на библиотеку и подробности: https://pypi.org/project/python-box/
источник
Используйте
__getattr__
, очень просто, работает в Python 3.4.3Вывод:
источник
Сам язык не поддерживает это, но иногда это все еще является полезным требованием. Помимо рецепта Bunch, вы также можете написать небольшой метод, который может получить доступ к словарю, используя пунктирную строку:
который бы поддерживал что-то вроде этого:
источник
Чтобы основываться на ответе epool, эта версия позволяет вам получить доступ к любому внутреннему диктату через оператор точки:
Например,
foo.bar.baz[1].baba
возвращает"loo"
.источник
iteritems()
наitems()
иxrange()
сrange()
Если кто-то решит окончательно преобразовать это
dict
в объект, это должно быть сделано. Вы можете создать одноразовый объект непосредственно перед доступом.источник
Я закончил тем, что пытался ОБА AttrDict и Букетбиблиотеки и обнаружили, что они могут быть медленными для моего использования. После того, как мы с другом изучили его, мы обнаружили, что основной метод написания этих библиотек приводит к агрессивной рекурсии библиотеки через вложенный объект и копированию объекта словаря. Имея это в виду, мы сделали два ключевых изменения. 1) Мы сделали атрибуты с отложенной загрузкой 2) вместо создания копий словарного объекта, мы создаем копии легкого прокси-объекта. Это окончательная реализация. Увеличение производительности при использовании этого кода невероятно. При использовании AttrDict или Bunch только эти две библиотеки потребляли 1/2 и 1/3 соответственно моего времени запроса (что !?). Этот код сократил это время практически до нуля (где-то в диапазоне 0,5 мс). Это, конечно, зависит от ваших потребностей, но если вы используете эту функцию в своем коде,
Смотрите оригинальную реализацию здесь по адресу https://stackoverflow.com/users/704327/michael-merickel .
Следует также отметить, что эта реализация довольно проста и не реализует все методы, которые могут вам понадобиться. Вам нужно будет написать их, как требуется, для объектов DictProxy или ListProxy.
источник
Я хотел бы бросить свое собственное решение в кольцо:
https://github.com/skorokithakis/jsane
Он позволяет вам анализировать JSON во что-то, к чему вы можете получить доступ
with.attribute.lookups.like.this.r()
, в основном потому, что я не видел этот ответ до того, как начал работать над ним.источник
KeyError
- одна из них. Когда один доступ к ключу, который не существует, все, что ему нужно сделать, это вернуться,None
как в JS. Я большой поклонник автовивификации как для чтения, так и для письма. Ваша библиотека ближе всего к идеалу.Не прямой ответ на вопрос ОП, но вдохновленный и, возможно, полезный для некоторых .. Я создал объектно-ориентированное решение с использованием внутреннего
__dict__
(ни в коем случае не оптимизированного кода)источник
Один простой способ получить точечный доступ (но не доступ к массиву) - использовать простой объект в Python. Как это:
... и используйте это так:
... чтобы преобразовать его в диктовку:
источник
Это решение является усовершенствованным по сравнению с тем, которое предлагает epool, чтобы удовлетворить требование OP о последовательном доступе к вложенным диктовкам. Решение от epool не позволило получить доступ к вложенным dicts.
С помощью этого класса, теперь можно сделать что - то вроде:
A.B.C.D
.источник
Это также работает с вложенными диктовками и гарантирует, что добавляемые позже диктанты ведут себя одинаково:
источник
Ответ @ derek73 очень аккуратный, но его нельзя мариновать или (глубоко) копировать, и он возвращает
None
отсутствующие ключи. Код ниже исправляет это.Изменить: я не видел ответ выше, который касается точно такой же точки (голосование). Я оставляю ответ здесь для справки.
источник
Решение вид деликатный
источник