1. Сначала используем просто аттрибуты, пока явно не появится нужда к использованию чего-то более сложного:
value = 'something'
obj.attribute = value
value = obj.attribute
del obj.attribute
2. Теперь появилась нужда контролировать чтение/изменение аттрибута, но мы не хотим менять публичное API объекта:
class Obj:
"""property demo"""
@property
def attribute(self): # implements the get - this name is *the* name
return self._attribute
@attribute.setter
def attribute(self, value): # name must be the same
self._attribute = value
@attribute.deleter
def attribute(self): # again, name must be the same
del self._attribute