0

I'm trying to understand property in depth following this article.

https://www.programiz.com/python-programming/property

class Celsius:
    def __init__(self, temperature = 0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    def get_temperature(self):
        print("Getting value")
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

    temperature = property(get_temperature,set_temperature)

One thing that intrigues me is how the _temperature and temperature variable works.

As per this article,

The attribute temperature is a property object which provides interface to this private variable.

How does this interface functionality provided in python?

c = Celsius()
print(dir(c))

When I print the dir(c) it shows the following -

['__doc__', '__init__', '__module__', 'get_temperature', 'set_temperature', 'temperature', 'to_fahrenheit']

The _temperature variable is hidden.

When I inherit the Celsius(object) from object class that shows a different result -

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_temperature', 'get_temperature', 'set_temperature', 'temperature', 'to_fahrenheit']
sentence
  • 8,213
  • 4
  • 31
  • 40
user1050619
  • 19,822
  • 85
  • 237
  • 413
  • 2
    Properties only work with new-style classes, which in Python 2 are those that *expicitly* inherit from `object`. – chepner May 02 '19 at 19:06

1 Answers1

0

property(get_temperature,set_temperature) is a descriptor, which means that when you access it on an instance, you get custom behaviour. A descriptor is an object that provides __get__(), __set__() and / or __del__() methods.

You can find details about descriptors here: https://docs.python.org/3/howto/descriptor.html

property objects in particular allow you to supply get and set methods that will be called when you try to access or set the object.

The modern idiom is to use decorator syntax for this:

class Celsius:
    def __init__(self, temperature = 0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    @property
    def temperature(self):
        print("Getting value")
        return self._temperature

    @temperature.setter
    def temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value
Aaron Bentley
  • 1,332
  • 8
  • 14
  • This doesn't address the OP's primary issue, which is that they are using Python 2 and old-style classes don't support the descriptor protocol. – chepner May 03 '19 at 12:35
  • @chepner I felt like the core of the post was "How does this interface functionality provided in python?" – Aaron Bentley May 04 '19 at 16:40