I see that your setters just log a message and then simply assign the value - in fact, your accepted answer just assigns the value. Are you using this pattern because it is the Accepted Practice / Conventional Wisdom in some other language, perhaps one whose name starts with "J"? If so, then please learn that the Pythonic approach to this same design is the much simpler:
class Of2010(object):
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
No do-nothing setters, no intermediate function calls just to assign a value. "What?!", you say? "Public exposure to member variables?!!" Well, yes actually.
Look at these classes from the standpoint of client code. To use your class, clients create an object, and then assign property "a" using:
obj = Of2010()
obj.a = 42
Remarkably, this is the exact same code for the 5-liner class I posted above.
Why does the J-language encourage the more verbose property style? To preserve the class interface in the event of future change in requirements. If at some point in time, some other value of the object must change in concert with any changes to a, then you must implement the property mechanism. Sadly, the J-language exposes the nature of the attribute access mechanism to the client code, so that to introduce a property at some point in the future is an intrusive refactoring task that will require a rebuild of all clients that make use of that class and its "a" attribute.
In Python, such is not the case. Access to the object's "a" attribute is determined at runtime in the caller. Since direct access and property access both "look" the same, your Python class preserves this interface even though the actual mechanism is different. What matters is that it is identical as far as the client code is concerned.
So in Java, one introduces this property complexity right from the inception of this class (and in fact, by Accepted Practice, of all classes), on the off-chance that it may become necessary some day in the future. With Python, one can start by implementing the Simplest Thing That Could Possibly Work, that is, direct access to simple member variables, leaving the complex approach for the time in the future that the extra stuff is actually required and of value. Since that day may never actually come, this is a huge jump forward in getting that first working version of your code out the door.