class AssignableSetattr(type):

    def __new__(mcls, name, bases, attrs):

        def __setattr__(self, attr, value):
            object.__setattr__(self, attr, value)
init_attrs = dict(attrs)
init_attrs['__setattr__'] = __setattr__
init_cls = super(AssignableSetattr, mcls).__new__(mcls, name, bases, init_attrs
    )
real_cls = super(AssignableSetattr, mcls).__new__(mcls, name, (init_cls,),
    attrs)
init_cls.__real_cls = real_cls
return init_cls

def __call__(cls, *args, **kwargs):
    self = super(AssignableSetattr, cls).__call__(*args, **kwargs)
print('Created', self)
real_cls = cls.__real_cls
self.__class__ = real_cls
return self


class Foo(object, metaclass=AssignableSetattr):
    pass

def __init__(self, a, b):
    self.a = a
self.b = b
for key, value in list(process(a).items()):
    setattr(self, key, value)

def __setattr__(self, attr, value):
    frob(self.b)
super(Foo, self).__setattr__(attr, value)

def process(a):
    print('processing')
return {'c': 3 * a}

def frob(x):
    print('frobbing', x)
myfoo = Foo(1, 2)
myfoo.d = myfoo.c + 1
Переопределение __setattr__ во время выполнения