Класс Python как хранилище данных - PullRequest
0 голосов
/ 04 марта 2012

Я пытаюсь написать класс Python, который действует как хранилище данных. Поэтому вместо использования словаря, например, я хочу получить доступ к своим данным как class.foo и по-прежнему иметь возможность выполнять все такие крутые вещи, как перебирать их как для x в классе данных .

Вот что я придумал:

class MyStore(object):
    def __init__(self, data):
        self._data = {}
        for d in data:
            # Just for the sake of example
            self._data[d] = d.upper()

    def __iter__(self):
        return self._data.values().__iter__()

    def __len__(self):
        return len(self._data)

    def __contains__(self, name):
        return name in self._data

    def __getitem__(self, name):
        return self._data[name]

    def __getattr__(self, name):
        return self._data[name]


store = MyStore(['foo', 'bar', 'spam', 'eggs'])
print "Store items:", [item for item in store]
print "Number of items:", len(store)
print "Get item:", store['foo']
print "Get attribute:", store.foo
print "'foo' is in store:", 'foo' in store

И, видимо, это работает. Ура! Но как правильно реализовать настройку атрибута? Добавление следующего приводит к ограничению рекурсии на __getattr__:

def __setattr__(self, name, value):
    self._data[name] = value

Читая документы, я должен вызвать метод суперкласса (объекта) __setattr__, чтобы избежать рекурсии, но таким образом я не могу контролировать свой диктант self._data.

Может ли кто-нибудь указать мне правильное направление?

1 Ответ

5 голосов
/ 04 марта 2012

Попробуйте это:

def __setattr__(self, name, value):
    super(MyStore, self).__setattr__(name, value)
    self._data[name] = value

Тем не менее, вы можете сэкономить много хлопот, просто подклассифицировав что-то вроде dict:

class MyStore(dict):

    def __init__(self, data):
        for d in data:
            self[d] = d.upper()

    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        self[name] = value

store = MyStore(['foo', 'bar', 'spam', 'eggs'])
print "Store items:", [item for item in store]
print "Number of items:", len(store)
print "Get item:", store['foo']
print "Get attribute:", store.foo
print "'foo' is in store:", 'foo' in store
store.qux = 'QUX'
print "Get qux item:", store['qux']
print "Get qux attribute:", store.qux
print "'qux' is in store:", 'qux' in store

который выводит ...

Store items: ['eggs', 'foo', 'bar', 'spam']
Number of items: 4
Get item: FOO
Get attribute: FOO
'foo' is in store: True
Get qux item: QUX
Get qux attribute: QUX
'qux' is in store: True
...