Переписать {} в Python - PullRequest
       7

Переписать {} в Python

3 голосов
/ 03 января 2012

Я хочу сделать dict int, к которому вы можете получить доступ следующим образом:

>>> my_dict["property'] = 3
>>> my_dict.property
3

Итак, я сделал это:

class DictAsMember(dict):
    def __getattr__(self, name):
        return self[name]

Это отлично работает, но если у вас есть вложенные диктовки, это не работает, например:

my_dict = DictAsMember()
my_dict["property"] = {'sub': 1}

Я могу получить доступ к my_dict.property, но логически я не могу сделать my_dict.property.sub, потому что свойство является dict по умолчанию, поэтому я хочу перезаписать dict по умолчанию, поэтому вы можете использовать {}.

Возможно ли это?

Ответы [ 2 ]

7 голосов
/ 03 января 2012

Одним из способов решения этой проблемы является перенос словарей по умолчанию с использованием DictAsMember перед возвратом их в методе __getattr__:

class DictAsMember(dict):
    def __getattr__(self, name):
        value = self[name]
        if isinstance(value, dict):
            value = DictAsMember(value)
        elif isinstance(value, list):
            value = [DictAsMember(element)
                     if isinstance(element, dict)
                     else element
                     for element in value]

        return value

my_dict = DictAsMember()
my_dict["property"] = {'sub': 1}
print my_dict.property.sub    # 1 will be printed

my_dict = DictAsMember()
my_dict["property"] = [{'name': 1}, {'name': 2}]
print my_dict.property[1].name    # 2 will be printed
2 голосов
/ 03 января 2012

Вместо того, чтобы писать свой собственный класс для реализации нотации my_dict.property (это называется нотацией объекта), вы могли бы вместо этого использовать именованные кортежи. На именованный кортеж можно ссылаться, используя объект, такой как переменная привязка или стандартный синтаксис кортежа. Из документации

[named tuple] используется для создания объектов, подобных кортежу, у которых есть доступные поля поиск по атрибутам, а также возможность индексирования и повторяемости.

В качестве примера их использования:

from collections import *

my_structure = namedtuple('my_structure', ['name', 'property'])
my_property  = namedtuple('my_property', ['sub'])

s = my_structure('fred', my_property(1))

s # my_structure(name='fred', property=my_property(sub=1)) will be printed

s.name # 'fred' will be printed

s.property # my_property(sub=1) will be printed

s.property.sub # 1 will be printed

См. Также принятый ответ на этот вопрос , где приведена хорошая сводка именованных кортежей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...