Using python 2.7, suppose I have a Test
class with the new-style class syntax defined below.
class Test(object):
def __init__(self):
self._a = 5
@property
def a(self):
return self._a
@a.setter
def a(self, val):
self._a = val
t = Test()
print t.a
t.a = 4
print t.a
print t._a
Run the code above will print 5,4,4
which is the desired behavior.
However, if I change the first line of the code above to class Test:
then the results becomes 5,4,5
.
Does anyone know what causes this difference in output?
Descriptors are not guaranteed to be invoked for old-style classes. From the docs:
So, what's going on here is that
Test.a.__set__
is never being invoked, you are simply adding ana
attribute tot
:What should really surprise you is why does the
T.a.__get__
work here at all?And the answer to that is that in Python 2.2, old-style classes were reimplemented to use descriptors, and that is an implementation detail that should not be relied on. See this question, and the linked issue.
Bottom line, if you are using descriptors, you should only be using them with new-style classes.
Note, if I do use a new-style class, it works as it should: