42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
import collections
|
|
import warnings
|
|
|
|
class MetaBunch(type):
|
|
def __prepare__(name, *bases, **kwargs):
|
|
return collections.OrderedDict()
|
|
|
|
def __new__(meta_cls, cls_name, bases, cls_dict):
|
|
def __init__(self, **kw):
|
|
for k in self.__defaults__:
|
|
setattr(self, k, self.__defaults__[k])
|
|
for k in kw:
|
|
setattr(self, k, kw[k])
|
|
|
|
def __repr__(self):
|
|
rep = ['{}={!r}'.format(k, getattr(self, k))
|
|
for k in self.__defaults__
|
|
if getattr(self, k) != self.__defaults__[k]
|
|
]
|
|
return '{}({})'.format(cls_name, ', '.join(rep))
|
|
|
|
new_dict = { '__slots__':[],
|
|
'__defaults__':collections.OrderedDict(),
|
|
'__init__':__init__, '__repr__':__repr__, }
|
|
|
|
for k in cls_dict:
|
|
if k.startswith('__') and k.endswith('__'):
|
|
if k in new_dict:
|
|
warnings.warn(
|
|
"Can't set attr {!r} in bunch-class {!r}".
|
|
format(k, cls_name))
|
|
else:
|
|
new_dict[k] = cls_dict[k]
|
|
else:
|
|
new_dict['__slots__'].append(k)
|
|
new_dict['__defaults__'][k] = cls_dict[k]
|
|
|
|
return super().__new__(meta_cls, cls_name, bases, new_dict)
|
|
|
|
class Bunch(metaclass=MetaBunch):
|
|
pass
|