osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

property confusion


On 21/02/2014 18:58, K Richard Pixley wrote:
> Could someone please explain to me why the two values at the bottom of
> this example are different?
>
> Python-3.3 if it makes any difference.
>
> Is this a difference in evaluation between a class attribute and an
> instance attribute?

Yes, see below.


> --rich
>
> class C:
>      def __init__(self):
>          self._x = None
>
>      def getx(self):
>          print('getx')
>          return self._x
>      def setx(self, value):
>          print('setx')
>          self._x = value
>      def delx(self):
>          print('delx')
>          del self._x
>      x = property(getx, setx, delx, "I'm the 'x' property.")
>
> class D:
>      def getx(self):
>          print('getx')
>          return self._x
>      def setx(self, value):
>          print('setx')
>          self._x = value
>      def delx(self):
>          print('delx')
>          del self._x
>
>      def __init__(self):
>          self._x = None
>          self.x = property(self.getx, self.setx, self.delx, "I'm the 'x'
> property.")
>
> type(C().x)
> type(D().x)

Properties are implemented as descriptors, i.e. objects that have 
__get__, __set__ and/or __delete__ methods:

http://docs.python.org/3/reference/datamodel.html#invoking-descriptors

If a is an instance and type(a) has an attribute named 'x' which is a 
descriptor then a.x is transformed into

type(a).__dict__['x'].__get__(a, type(a));

in the case of your code, C.__dict__['x'] is the property you defined, 
and its __get__ method is just getx. But because of the way attribute 
lookup works for descriptors, properties don't work as attributes of 
instances as is the case with D(); D().x just gives you 
D().__dict__['x'] which is the property itself.