0

I want a method get called when a member variable, which is a dictionary, is edited(in any way).

Is there any way I can achieve this without declaring a new class?

For example,

class MyClass:
    def __init__(self):
        self.dictionary = {}

    def __setattr__(self, key, value):
        super().__setattr__(key, value)
        # DO SOMETHING

This will ONLY work when I use

self.dictionary = {}

, not working when

self.dictionary[some_key] = some_value

And @property - @dictionary.setter will result the same.

Yes, I know it'll call __setitem__ of that dict, so making a new class such as

class MyDict(dict):
    # override __setitem__ and other methods called when modifying the values

will work.

But the thing is,

  1. I need to use for list as well, and there are lots of methods that modifies the value.

  2. I need to use Dict[int, List[int]] like this, and it'll be very messy.

  3. I need to dump that data with pickle, so I'll need to define __getstate__ and __setstate__ to avoid weakref error if I make a new class.

+For clearance, what I ultimately want is a method of MyClass that is called when all of the some_func's cases.

class MyClass:
    def __init__(self):
        self.data: Dict[int, List[int]] = {}

    def some_func(self):
        self.data[1].append(10)
        self.data.popitem()
        self.data[2] = []
        # And any other things that changes the data...

I would appreciate any idea, thank you.

yeshjho
  • 350
  • 2
  • 11
  • This may help with the dict part of your question: https://stackoverflow.com/questions/26189090/python-detect-if-any-element-in-a-dictionary-changes – benvc May 20 '19 at 16:34
  • Can't you also create your own `list` subclass? i.e. `class MyList(list)`? – martineau May 20 '19 at 16:51
  • Consider what you're trying to accomplish: you want to change the functionality of *one* dict out of all dicts in your application -- you want it to have additional functionality. This pretty much *defines* what a subclass **is**. Yes, you need to alter the class methods that manipulate the object, such that they intercept and update in the fashion you need. – Prune May 20 '19 at 16:58
  • @martineau Yes I could, but using that in ```Dict[int, List[int]]``` would be very messy since a change in that list should call a function of ```MyClass``` – yeshjho May 20 '19 at 17:01
  • You might be able to adapt my answer to the question [How to wrap every method of a class?](https://stackoverflow.com/questions/11349183/how-to-wrap-every-method-of-a-class). Although I'm not sure what you meant by "without declaring a new class". – martineau May 20 '19 at 17:02
  • @Prune Yes, I'm aware of that, and what I'm asking is 'Is there any other way to avoid that', since it would be very unnecessarily lengthy to implement all those functions to call the upper ```MyClass``'s function I'm hoping to be called. – yeshjho May 20 '19 at 17:04
  • 1
    @martineau I meant 'not subclassing dict or list' by that, but anyway, the link you gave will be helpful for lessening the length needed to subclass, thank you! – yeshjho May 20 '19 at 17:08

0 Answers0