import sys


def attribute(name, type=None, default=None, ro=False):
    @property
    def fn(self):
        return getattr(self, '_' + name, default)

    if not ro:
        @fn.setter
        def fn(self, value):
            if type is not None and not isinstance(value, type):
                raise TypeError
            setattr(self, '_' + name, value)

    sys._getframe(1).f_locals[name] = fn


class Doge:
    attribute('such_var',  int, 10)
    attribute('much_data', str)


d = Doge()
print(d.such_var, d.much_data)
d.such_var  = 12
d.much_data = 'very test'
print(d.such_var, d.much_data)
d.such_var = 'omg error'