Классы и словари в Python для хранения пар ключ-значение - PullRequest
3 голосов
/ 09 декабря 2011

Мне нужно определить некоторые параметры ключ-значение для настройки поведения класса.У меня два требования:

  • Чтобы иметь возможность обрабатывать их программно
  • Чтобы иметь возможность создавать более конкретные конфигурации, которые перезаписывают некоторые значения.

Естественным подходом для первого требования является использование dict (чтобы я мог циклически перебирать ключи, значения или элементы с помощью цикла for), но для второго требования представляется более уместным использовать иерархию классов и позволитьмеханизм поиска атрибутов для выполнения работы (плюс я получаю другие плюсы, такие как возможность использовать свойства для некоторых значений).

Есть ли способ получить лучшее из обоих миров?


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

Я думаю, в конце концов, я мог бы просто использовать dict.copy + dict.update для конкретных экземпляров (я могу жить без свойств).

Ответы [ 5 ]

2 голосов
/ 09 декабря 2011

Так или иначе, в соответствии с тем, что было предложено в комментарии Фабио, я бы заметил, что они не являются взаимоисключающими, учитывая, что в Python [почти] все является объектом (включая классы!).Одним из очевидных решений является - снова цитируя Фабио - создание подкласса dict.Другой - создать свой собственный класс, начиная с collections.abc контейнеров (используя абстрактный базовый класс (abc), это не является обязательным требованием, но, вероятно, наиболее питонскимреализовать свой собственный контейнер с нуля).

HTH!

1 голос
/ 03 октября 2013

Если вы можете использовать python 3.3 ChainMap - это именно то, что вам нужно.

http://docs.python.org/3.3/library/collections#collections.ChainMap

Это в основном список словарей, в котором каждый ключ будет последовательно искать заданный ключ до тех пор, покасовпадение найдено.

Собственно, вот код для его использования в 2.7:

http://code.activestate.com/recipes/305268-chained-map-lookups/

1 голос
/ 09 декабря 2011

это то, что вам нужно?

class my_dict(dict):
    def __getattr__(self, name):
        return self[name]
    def __setattr__(self, name, value):
        self[name] = value

d = my_dict()
d.key = "value"
print d.key       #>>>value

for k,v in d.items():
    print k,v     #>>>key value
0 голосов
/ 09 декабря 2011

Вот мой дубль:

class Config(object):
    def _keys(self):
        return (name for name in dir(self) if not name.startswith('_'))
    __iter__ = _keys

    def _values(self):
        return (getattr(self, name) for name in self)

    def _items(self):
        return ((name, getattr(self, name)) for name in self)

>>> class Foo(Config):
...     bar = 3
...     baz = 'spam'
...
>>> class Sub(Foo):
...     bar = 4
...
>>> x = Sub()
>>> list(x._items())
[('bar', 4), ('baz', 'spam')]
>>>
0 голосов
/ 09 декабря 2011

Вы можете просто использовать именованные кортежи . См. здесь и принятый ответ на этот вопрос для хорошего ознакомления с ними. Некоторые важные моменты из этого ответа:

  • Они были добавлены в Python 2.6 и Python 3.0, хотя для реализации в Python 2.4 существует рецепт .

  • Именованные кортежи обратно совместимы с обычными кортежами

Кроме того, именованные кортежи имеют ряд полезных методов, таких как _fields для получения имен используемых и _asdict метод, который возвращает (упорядоченный) dict содержимого именованного кортежа.

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