Home > Software engineering >  Class variables not updating as expected
Class variables not updating as expected

Time:03-09

I am attempting to create class variables that are dependent on other class variables, and I am having some problems. I will explain with code:

A simple example of the code structure is provided below:

class strategy():
    
    def __init__(self):
        self.data = {'AAPL':140, 'TSLA':225, 'GOOG':175}
        
        self.insights = dict(filter(lambda x : x[1] > 150, self.data.items()))

As a test, I run the script and then run the following commands with the shown results:

s = strategy()

s.data
% {'AAPL': 140, 'TSLA': 225, 'GOOG': 175}

s.insights
% {'TSLA': 225, 'GOOG': 175}

At this point everything has worked as expected. The self.insights variable has been populated using self.data. However, if I update the data variable, the insights do not change:

s.data['GME'] = 500

s.data
% {'AAPL': 140, 'TSLA': 225, 'GOOG': 175, 'GME': 500}

s.insights
% {'TSLA': 225, 'GOOG': 175}

As you can see, the self.data variable updates successfully, but the self.insights variable does not change. It was my understanding that if I define a variable as a function of another variable, they will update together. Is this not the case?

CodePudding user response:

You can use the builtin @property decorator to define a function to get a value which updates based on other class variables:

class Strategy:
    def __init__(self):
        self.data = {"AAPL": 140, "TSLA": 225, "GOOG": 175}
    @property
    def insights(self):
        return {k: v for k, v in self.data.items() if v > 150}

    
s = Strategy()
s.data
>> {'AAPL': 140, 'TSLA': 225, 'GOOG': 175}
s.insights
>> {'TSLA': 225, 'GOOG': 175}
s.data["GME"] = 500
s.data
>> {'AAPL': 140, 'TSLA': 225, 'GOOG': 175, 'GME': 500}
s.insights  # Updated successfully 
>> {'TSLA': 225, 'GOOG': 175, 'GME': 500}

CodePudding user response:

Guidance from sj95126 and Robin Zigmond resulted in the following code that works as originally desired:

class strategy():
    
    def __init__(self):
        self.data = {'AAPL':140, 'TSLA':225, 'GOOG':175}
    
    @property
    def insights(self):
        return dict(filter(lambda x : x[1] > 150, self.data.items()))

The getter/setter functionality of the @property decorator is used here with the following results:

>>> s = strategy()

>>> s.data
{'AAPL': 140, 'TSLA': 225, 'GOOG': 175}

>>> s.insights
{'TSLA': 225, 'GOOG': 175}

>>> s.data['GME'] = 500

>>> s.data
{'AAPL': 140, 'TSLA': 225, 'GOOG': 175, 'GME': 500}

>>> s.insights
{'TSLA': 225, 'GOOG': 175, 'GME': 500}

As you can see, self.insights updates as expected and there is no excess data transfer or redundant data.

  • Related