3

I want to create a simple Class which just stores / holds data as class attributes without creating an instance as an object.

Simple as that which can be accessed from everywhere in my code:

class DATA:
    foo = {}
    bar = {}

Now I wanted to go one step further and always save changes to foo and bar in a file, e.g. shelve, still without creating an object / instance.

My initial thought was something like this:

class DATA2:
    foo = {}
    bar = {}
    _shelve = False

    def __setattr__(self, name, value):
        if self._shelve is False:
            self.__dict__['_shelve'] = shelve.open('datastorage.shelve')

        self.__dict__['_shelve'][name] = value
        self.__dict__[name] = value

But __setattr__ cannot be used like this using the self argument. And it seems there is no __setattr__ method on a class instance.

My second approach was to use a meta class which creates a class instance in the background hiding it from the code:

class _DATA_MetaClass(type):
    foo = {}
    bar = {}
    _shelve = False

    def __setattr__(self, name, value):
        if self._shelve is False:
            self.__dict__['_shelve'] = shelve.open('datastorage.shelve')

        self.__dict__['_shelve'][name] = value
        self.__dict__[name] = value

class DATA(object):
    __metaclass__ = _DATA_MetaClass

DATA.x = 'val'

This does not work, it yields:

TypeError: 'dictproxy' object does not support item assignment

Why is that?

1 Answer 1

1

You can use the __setattr__ method of the super class (which is type) to set the custom attributes:

class _DATA_MetaClass(type):
    foo = {}
    bar = {}
    _shelve = False

    def __setattr__(self, name, value):
        if self._shelve is False:
            super(_DATA_MetaClass, self).__setattr__('_shelve', shelve.open('datastorage.shelve'))

        self._shelve[name] = value
        super(_DATA_MetaClass, self).__setattr__(name, value)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.