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.