.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/oop/property.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_oop_property.py: =============== 3.11 property =============== .. GENERATED FROM PYTHON SOURCE LINES 8-12 Let's say we have a for human body metabolism which has temperature as one of its parameters(attributes) and we want to have controle over this parameter in such a way that we can set the temperature from outside as well while the model itself also changes the temperature parameter when it is run. .. GENERATED FROM PYTHON SOURCE LINES 14-27 .. code-block:: default class Model: def __init__(self, temp): self.temp = temp x = Model(39) print(x.temp) x.temp = 35 print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 39 35 .. GENERATED FROM PYTHON SOURCE LINES 28-31 Thus we can set the temperature from outside the class. But what if after some time we want to set certain condition on temperature attribute such as the temperature should never be above 45 degrees and below 20 degrees. .. GENERATED FROM PYTHON SOURCE LINES 34-54 .. code-block:: default class Model: def __init__(self, temp): self.set_temp(temp) def set_temp(self, x): if x > 45: x = 45 if x < 20: x = 20 self.temp = x def get_temp(self): return self.temp x = Model(39) print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 39 .. GENERATED FROM PYTHON SOURCE LINES 55-56 We can set the temperature as before but then we may violate the condition as well .. GENERATED FROM PYTHON SOURCE LINES 58-62 .. code-block:: default x.temp = 55 print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 55 .. GENERATED FROM PYTHON SOURCE LINES 63-64 In order to set the temperature, we have to now make use of method `set_temp`. .. GENERATED FROM PYTHON SOURCE LINES 66-70 .. code-block:: default x.set_temp(55) print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 45 .. GENERATED FROM PYTHON SOURCE LINES 71-72 if we want to change the temperature value based upon its current value, we can do as following .. GENERATED FROM PYTHON SOURCE LINES 74-79 .. code-block:: default print(x.get_temp()) x.set_temp(x.get_temp() * 0.9) print(x.get_temp()) .. rst-class:: sphx-glr-script-out .. code-block:: none 45 40.5 .. GENERATED FROM PYTHON SOURCE LINES 80-91 we were able to decrease the temperature but there are two problems. * First the statement ``x.set_temp(x.get_temp()*0.9)`` does not look so elegant, it would have been much better and clearer if we could do like ``x.temp = x.temp*0.9``. * There are two ways to set and get temperature which is against the zen of python [1]_ which states **There should be one-- and preferably only one --obvious way to do it**. Based upon above discussion we would have liked ``temp`` to behave like attribute (`x.temp`) but still be able to perform some checks on it behind the scene (which we could do by ``x.temp()``) and there should be only one way to set and get its value as well. We can solve the second problem by making ``temp`` a private attribute i.e. by making it ``__temp``, and then we have to use only setters ``x.set_temp()`` and getters ``x.get_temp``. .. GENERATED FROM PYTHON SOURCE LINES 94-117 .. code-block:: default class Model: def __init__(self, temp): self.set_temp(temp) def set_temp(self, x): if x > 45: x = 45 if x < 20: x = 20 self.__temp = x def get_temp(self): return self.__temp x = Model(39) print(x.get_temp()) x.set_temp(55) print(x.get_temp()) .. rst-class:: sphx-glr-script-out .. code-block:: none 39 45 .. GENERATED FROM PYTHON SOURCE LINES 118-120 But python provides a better solution to solve both of above two problems i.e. the `@property` decorator. .. GENERATED FROM PYTHON SOURCE LINES 123-150 .. code-block:: default class Model: def __init__(self, temp): self.temp = temp @property def temp(self): # get temperature from the model through some process return self._temp @temp.setter def temp(self, x): if x > 45: x = 45 if x < 20: x = 20 self._temp = x return x = Model(39) print(x.temp) x.temp = x.temp * 0.9 print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 39 35.1 .. GENERATED FROM PYTHON SOURCE LINES 151-156 Just a side note, we don't have provide the default value of `temp` upon class initiation. We can make the method to get the current temperature state of the model. In many cases our model will be saved in an external file. For simplicity, suppose, our model is saved as dictionary `MODEL`. We can make use of property to manipulate `temp`. .. GENERATED FROM PYTHON SOURCE LINES 158-189 .. code-block:: default MODEL = {'temp': 39} class Model: def __init__(self): pass @property def temp(self): # get temperature from the model through some process t = MODEL['temp'] return t @temp.setter def temp(self, x): if x > 45: x = 45 if x < 20: x = 20 MODEL['temp'] = x return x = Model() print(x.temp) x.temp = x.temp * 0.9 print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 39 35.1 .. GENERATED FROM PYTHON SOURCE LINES 190-191 run the model and check the temperature again .. GENERATED FROM PYTHON SOURCE LINES 193-196 .. code-block:: default MODEL .. rst-class:: sphx-glr-script-out .. code-block:: none {'temp': 35.1} .. GENERATED FROM PYTHON SOURCE LINES 197-200 What happens if we skip setter i.e. `@temp.setter`? This will make the attribute readonly, and any user of the class will not be able to modify its value from outside the class using instance. .. GENERATED FROM PYTHON SOURCE LINES 202-222 .. code-block:: default MODEL = {'temp': 39} class Model: def __init__(self): pass @property def temp(self): # get temperature from the model through some process t = MODEL['temp'] return t x = Model() print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 39 .. GENERATED FROM PYTHON SOURCE LINES 223-230 .. code-block:: default # uncomment following line # x.temp = x.temp * 0.9 # AttributeError print(x.temp) .. rst-class:: sphx-glr-script-out .. code-block:: none 39 .. GENERATED FROM PYTHON SOURCE LINES 231-234 run the model and check the temperature again .. [1] ``_ .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 0.006 seconds) .. _sphx_glr_download_auto_examples_oop_property.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/AtrCheema/python-seekho/master?urlpath=lab/tree/notebooks/auto_examples/oop/property.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: property.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: property.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_