0

I have a class that inherits from the dict class. In the example below, I define two keys 'x' and 'x2' with default value

class myClass(dict):
   def __init__(self,*arg,**kw):
      super(myClass, self).__init__(*arg, **kw)
      self['x']=2
      self['x2']=self['x']*self['x']

I want that they are linked in a way so that if I modify 'x', 'x2' is updated by x*x, and if I modify 'x2', then 'x' is updated to sqrt(x)

I found a post that explains a solution to do that for class attributes: In class object, how to auto update attributes?

However, I cannot find a way to twist this example to make it work for dictionary keys. Does anyone has a clue about how to do it?

Thanks!

BayesianMonk
  • 540
  • 7
  • 23
  • If you have only two keys is their a particular reason why you use a dictionary ? – scharette Jul 26 '18 at 14:12
  • You might want to try [overriding `dict.__setitem__()`](https://stackoverflow.com/questions/2060972/subclassing-python-dictionary-to-override-setitem), and doing things in that method. – Green Cloak Guy Jul 26 '18 at 14:12
  • @scharette: the class I intend to create will be more complicated than the example I provided here for the sake of simplicity! – BayesianMonk Jul 26 '18 at 14:45

1 Answers1

1

For sublassing dictionary is recommended sublass from collections.UserDict, not dict. With UsedDict, all your content is stored in data variable. Manual pages here.

For desired functionality, you can redefine __setitem__ special method:

import math
from collections import UserDict

class myClass(UserDict):
    def __init__(self,*arg,**kw):
        super(myClass, self).__init__(*arg, **kw)

        self.data['x'] = 2
        self.data['x2']= self['x'] * self['x']

    def __setitem__(self, key, value):
        super().__setitem__(key, value)
        if key == 'x':
            self.data['x2'] = value * value
        elif key == 'x2':
            self.data['x2'] = math.sqrt(value)

c = myClass()
print(c['x'])
print(c['x2'])
print('-' * 80)
c['x'] = 4
print(c['x'])
print(c['x2'])
print('-' * 80)
c['x2'] = 9
print(c['x'])
print(c['x2'])

Output:

2
4
--------------------------------------------------------------------------------
4
16
--------------------------------------------------------------------------------
4
3.0
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • Thanks, it works! However, I could not really understand the difference between `UserDict ` and `Dict`, even with the Manual page link you provide. Wouldn't it be possible to do it with a normal `Dict`? – BayesianMonk Jul 26 '18 at 14:41