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?
CodePudding user response:
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)