Переопределите __getitem__ для обновления - PullRequest
0 голосов
/ 13 июня 2018

Я реализую класс, который наследуется от UserDict.Этот класс работает полностью, как ожидалось, но я хотел бы расширить его возможности.Я хотел бы, чтобы он прошел через все методы, которые были переопределены при работе со словарем.Примером может быть:

from collections import UserDict


class DummyClass(UserDict):
    def __init__(self):
        self.mine = {}
        self.data = self.mine

    def __getitem__(self, key):
        print("Doing some stuff here")
        return self.data[key]

    def __setitem__(self, key, value):
        print(f"Uses my __setitem__ {key} {value}")
        self.data[key] = value

При выполнении:

dd = DummyClass()
dd["one"] = {"two": 2}
print(f"First dict: {dd}") 

Вывод:

Uses my __setitem__ one {'two': 2}
First dict: {'one': {'two': 2}}

Однако

dd["one"].update({"two": 4})
print(f"New dict: {dd.keys()}")

будет использовать модифицированный getitem и использовать базовый метод update.

Doing some stuff here
New dict: {'one': {'two': 4}}

Я хотел бы, чтобы dd["one"] был объектом, который можно было изменить, вызвав измененный setitem без необходимости делать dd.update({"one": {"two": 4}})

Мой вопрос - какой путь лучшепойти об этом?В приведенном выше примере я должен вернуть объект с getitem, изменить его и вернуть?Мне бы хотелось, чтобы он был как можно более универсальным.

Он тесно связан с вопросом:

Подклассы словаря Python для переопределения __setitem __

Но яИнтересно, есть ли новый подход к этому сейчас.

Любая помощь приветствуется

1 Ответ

0 голосов
/ 13 июня 2018

Вы можете заключить внутренние словари, которые вам даны, в значения в другом экземпляре вашего класса.Если вы хотите, чтобы это происходило автоматически, я бы посоветовал сделать это для любого значения словаря, которое вы передаете в __setitem__, так как это позволит вам впоследствии изменить объект-оболочку, сохраняя ссылку на него в ваших данных.

Попробуйте что-то вроде этого:

def __setitem__(self, key, value):
    print(f"Uses my __setitem__ {key} {value}")
    if isisnstance(value, dict):
        wrapper = DummyClass()  # if __init__ accepts arguments use: value = DummyClass(value)
        wrapper.update(value)
        value = wrapper
    self.data[key] = value

Пример вывода:

>>> dd = DummyClass()

>>> dd["one"] = {"two": 2}
Uses my __setitem__ one {'two': 2}
Uses my __setitem__ two 2

>>> dd["one"].update({"two": 4})
Doing some stuff here
Uses my __setitem__ two 4

>>> print(dd)
{'one': {'two': 4}}
...