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.
__setattr__is called is in__init__when you do:self._treasure = "gold". And indeed, at this point, there is noself._attributes.object.__setattr__(self, "treasure", "gold")andobject.__setattr__(self, "_attributes", self._attributes = dict(self.__dict__))etc inside your implementation__init__in your original implementation need to useobject.__setattr__()(orsuper().__setattr__()) for_attributeas your class's__setattr__has been overridden, if your intention is to define_attributeis the mapping to store attributes.