Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Use of @property decorator
#11
Hi there,

I've defined an attribute, wave_coef, with the property decorator. It is a function of other attributes. Is there any way to store this value and not have it calculated each time I call it? And a way so the the object knows when the inputs have been changed and update the value?

class Vessel():    
    def __init__(self, class_notation, length):
        self.class_notation = class_notation
        self.length = length

    @property
    def wave_coef(self):
        table = {"R0" : 1,
         "R1" : 0.9,
         "R2" : 0.8,
         "R3" : 0.7,
         "R4" : 0.6,
         "R5" : 0.5,
         "R6" : 0.4}

        service_factor =  table[self.class_notation]    
        
        if (self.length <= 100):
            CW = 0.08 * self.length * service_factor
        else:
            CW = 6 + 0.02 * self.length * service_factor
            
        return CW


Thanks
Reply
#12
this will require to have setter for both length and class_notation and update the [internal] variable that will hold wave_coef whenever each of these these attributes change. And will be more open to [possible] errors.
In my opinion what you have now is better.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#13
It would look something like this

class Vessel():
    def __init__(self, class_notation, length):
        self._class_notation = class_notation
        self._length = length
        self.table = {"R0": 1,
                      "R1": 0.9,
                      "R2": 0.8,
                      "R3": 0.7,
                      "R4": 0.6,
                      "R5": 0.5,
                      "R6": 0.4}
        self._wave_coef = 0
        self.calc_wave_coef()

    @property
    def wave_coef(self):
        return self._wave_coef

    def calc_wave_coef(self):
        print('calculating wave_coef')
        service_factor = self.table[self._class_notation]

        if (self.length <= 100):
            CW = 0.08 * self._length * service_factor
        else:
            CW = 6 + 0.02 * self._length * service_factor

        self._wave_coef = CW

    @property
    def class_notation(self):
        return self._wave_coef

    @class_notation.setter
    def class_notation(self, value):
        self._class_notation = value
        self.calc_wave_coef()

    @property
    def length(self):
        return self._length

    @length.setter
    def length(self, value):
        self._length = value
        self.calc_wave_coef()


vessel = Vessel('R2', 2)
print(vessel.wave_coef)
print(vessel.wave_coef)
vessel.class_notation = 'R4'
print(vessel.wave_coef)
vessel.length = 1
print(vessel.wave_coef)
Output:
calculating wave_coef 0.128 0.128 calculating wave_coef 0.096 calculating wave_coef 0.048
Reply
#14
Another way, keep track of the previous values, only re calculate if they have changed.
class Vessel():
    def __init__(self, class_notation, length):
        self.class_notation = class_notation
        self.length = length
        self.previous_values = (None, None, None)

    @property
    def wave_coef(self):
        if self.previous_values[:2] == (self.class_notation, self.length):
            return self.previous_values[2]
        print('calculating wave_coef')
        table = {"R0": 1,
                 "R1": 0.9,
                 "R2": 0.8,
                 "R3": 0.7,
                 "R4": 0.6,
                 "R5": 0.5,
                 "R6": 0.4}
        service_factor = table[self.class_notation]

        if (self.length <= 100):
            CW = 0.08 * self.length * service_factor
        else:
            CW = 6 + 0.02 * self.length * service_factor

        self.previous_values = (self.class_notation, self.length, CW)
        return CW


vessel = Vessel('R2', 2)
print(vessel.wave_coef)
print(vessel.wave_coef)
vessel.class_notation = 'R4'
print(vessel.wave_coef)
vessel.length = 1
print(vessel.wave_coef)
Output:
calculating wave_coef 0.128 0.128 calculating wave_coef 0.096 calculating wave_coef 0.048
Reply
#15
Thanks a lot everyone.

(Jun-09-2020, 04:02 PM)buran Wrote: In my opinion what you have now is better.

I guess I can see why you would say so. The first code is much more simple and straightforward
Reply
#16
My last version, keeping track of the previous values is the better way to go, simpler and doesn't calculate when not necessary.
Reply
#17
(Jun-09-2020, 04:57 PM)ruy Wrote: I guess I can see why you would say so. The first code is much more simple and straightforward
yes + I don't think performance benefit of not calculating every time would be worth it. Second proposal by @Yoriz is fair compromise, but still it's open to mishandling if Vessel.previous_values property is changed by mistake.

EDIT: actually, yes, second proposal by @Yoriz is better compromise
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  the order of running code in a decorator function akbarza 2 479 Nov-10-2023, 08:09 AM
Last Post: akbarza
  Curious about decorator syntax rjdegraff42 14 1,976 May-03-2023, 01:21 PM
Last Post: rjdegraff42
  Subclass initialized property used in parent class method. Is it bad coding practice? saavedra29 5 1,680 Feb-07-2022, 07:29 PM
Last Post: saavedra29
  ABC Module and @property decorator, Pythonic Way? muzikman 21 5,495 Aug-18-2021, 06:08 PM
Last Post: muzikman
  @property vs __set__ / __get__ and __setattr__ / __getattr__ okhajut 1 3,254 Jun-15-2021, 03:48 PM
Last Post: snippsat
  Can property getters and setters have additional arguments? pjfarley3 2 2,990 Oct-30-2020, 12:17 AM
Last Post: pjfarley3
  decorator adamfairhall 0 1,539 Aug-18-2020, 08:38 AM
Last Post: adamfairhall
  Property price calculation oli_action 4 3,091 Jul-15-2020, 04:27 PM
Last Post: sridhar
  Problem adding keys/values to dictionary where keynames = "property" and "value" jasonashaw 1 2,014 Dec-17-2019, 08:00 PM
Last Post: jasonashaw
  strange class property KaliLinux 2 2,311 Nov-25-2019, 04:32 PM
Last Post: KaliLinux

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020