The following class decorator would do that:
def autoproperty(name, can_get=True, can_set=True, allow_null=False, default_value=0):
attribute_name = '_' + name
def getter(self):
return getattr(self, attribute_name, default_value)
def setter(self, value):
if not allow_null and value is None:
raise ValueError('Cannot set {} to None'.format(name))
setattr(self, attribute_name, value)
prop = property(getter if can_get else None, setter if can_set else None)
def decorator(cls):
setattr(cls, name, prop)
return cls
return decorator
but you could just as well create a property factory:
def autoproperty(attribute_name, can_get=True, can_set=True, allow_null=False, default_value=0):
def getter(self):
return getattr(self, attribute_name, default_value)
def setter(self, value):
if not allow_null and value is None:
raise ValueError('Cannot set {} to None'.format(name))
setattr(self, attribute_name, value)
return property(getter if can_get else None, setter if can_set else None)
then set that in the class with:
class SomeNonTrivialClass(object):
# ...
foo = autoproperty('_foo', can_get=True, can_set=True, allow_null=False, default_value=0)
The class decorator would make more sense if you needed to create multiple properties (perhaps with interdependencies) instead.