I am working on a python class that has declared properties, and in which I want to add extra attributes at object instanciation (passed in the init method). I want them to be read and written. Finally, I don't want the user to be able to declare custom attributes; it should raise an Error.
class Person:
__slots__ = ["_name", "__dict__"]
def __init__(self, name, extra_arg):
self.__dict__[extra_arg] = None
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
def __getattr__(self, item):
if item in self.__dict__:
return self.__dict__[item]
raise AttributeError(item)
person = Person("gribouille", "hello")
person.custom_attribute = value # I want to prevent this
In this example, I can't manage to prevent new attributes to be declared. When I override setattr method, it seems to collide with my property and I can't manage to retrieve my "name" attribute.
How about checking for existing attributes via hasattr
and __slots__
?
class Person:
__slots__ = ["_name", "__dict__"]
def __init__(self, name, extra_arg):
self.__dict__[extra_arg] = None
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
def __getattr__(self, item):
if item in self.__dict__:
return self.__dict__[item]
raise AttributeError(item)
def __setattr__(self, attr_name, attr_value):
if not (hasattr(self, attr_name) or attr_name in self.__slots__):
raise AttributeError(attr_name)
super().__setattr__(attr_name, attr_value)
person = Person("gribouille", "hello")
person.name = "test"
person.custom_attribute = None # Now: AttributeError: custom_attribute