1

I'm new to python and I wonder, if is possible to make a single method to manipulate with all class attributes, like:

class Test:
    def __init__(self, dict1 = {"test": 0}, dict2 = {"another_test": 0}):
        self.dict1= dict1
        self.dict2 = dict2

    def vary_attr(self, attr, key, value):
        self.attr[key] += value

x = Test()
x.vary_attr('dict1', 'test', 3)
x.vary_attr('dict2', 'another_test', 6)

print(x.dict1)

# Wishful output:
# {'test': 3}
# {'another_test': 6}

Obviously, this doesn't work, but it is possible to make it work? Having one method and through that method manipulate with both attributes dict1 and dict2?!

1 Answers1

2

Actually your use case is to first get the attribute which is dictionary, then make the necessary updates. You can use getattr to get the attribute then perform necessary operations.

class Test:
    def __init__(self, dict1 = {"test": 0}, dict2 = {"another_test": 0}):
        self.dict1= dict1
        self.dict2 = dict2

    def vary_attr(self, attr, key, value):
        # get class attribute by attribute name attr
        _atr = getattr(self, attr)
        _atr.update({key: _atr.get(key, 0)+value})

x = Test()
x.vary_attr('dict1', 'test', 3)
x.vary_attr('dict2', 'another_test', 6)
# x.dict1, x.dict2
# ({'test': 6}, {'another_test': 6})

Note, your use case doesn't require to set the attribute dynamically cause dict.update is a mutable function, but for other use cases, you can use setattr and pass self, attr, and value as parameters.

ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
  • 1
    Yes, I noticed that, setattr() works with attributes, but not with dictionaries. Your example works, but I probably don't wanna use update(), because if I make a typo, update() adds it as a new item.. Anyway thank you very much, you answered my question! – Tichomír Duchaplný Sep 18 '22 at 16:49
  • @TichomírDuchaplný `setattr` works with dictionary too, it's just convenient to call `update` for dictionaries else you need to make an extra copy of the dictionary, make the necessary changes, and finally pass it to `setattr` which is just unnecessary processing and makes it less efficient – ThePyGuy Sep 18 '22 at 17:04
  • 1
    As I said, I'm new to Python and I didn't know that, but thank for clarify. I finally went with other approach and I hope, this way is ok: `getattr(self, attr)[key] += value` – Tichomír Duchaplný Sep 18 '22 at 17:32
  • Yeah that's okay but it will throw error in case the key doesn't exist so you may want to handle that error. – ThePyGuy Sep 18 '22 at 17:35
  • 1
    Yes, that's the behavior I was looking for, thx! – Tichomír Duchaplný Sep 18 '22 at 17:40