example-code-2e/24-class-metaprog/metabunch/pre3.6/bunch.py
2021-09-10 12:34:39 -03:00

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