AttributeError and RecursionError happened when using `__setattr__` in python

61 Views Asked by At

I used super() as a part of the __setattr__ method to update a dictionary whenever an attribute value is set on an instance of a class; however, a warning reported as my class object has no such attribute '_attributes'. The code just like this:

class Vault:
    def __init__(self):
        self._treasure = "gold"
        self._attributes = dict(self.__dict__)

    def __setattr__(self, name, value):
        if name != "_attributes" and name not in self._attributes:
            print("attribute deleted!")
        self._attributes[name] = value
        super().__setattr__("_attributes", dict(self.__dict__))

    @property
    def treasure(self):
        if self.__dict__ != self._attributes:
            print("attribute deleted!")
        return self._treasure

v = Vault()
print(v.treasure)

Maybe there is an issue caused by the super()? I was new to use this method in Python and I was not sure, can someone help to explain it a bit? Another problem occurred as I initally thought the problem was caused by the line self._attributes[name] = value inside the __setattr__ method since '_attributes' had not yet defined when the instance is created, so I fixed my code as below but it still not work. The warning reported a Recursion Error saying that the maximum recursion depth exceeded.

class Vault:
    def __init__(self):
        self._treasure = "gold"

    def __setattr__(self, name, value):
        if name != "_attributes" and name not in self.__dict__:
            print("attribute deleted!")
        self.__dict__[name] = value
        self._attributes = dict(self.__dict__)

    @property
    def treasure(self):
        if self.__dict__ != self._attributes:
            print("attribute deleted!")
        return self._treasure

v = Vault()
print(v.treasure)

It will be super appreciated if someone may help me with this __setattr__ method and the bug fixing. This question is for my Python study and development, so it welcomes any answers and discussions. The goal of this code is to create a class named 'Vault' containing an attribute named 'treasure' which returns 'gold' under normal circumstances, but a warning message such as 'attribute deleted' if it detects any of its attributes have been changed.

0

There are 0 best solutions below