Python: Only allow attributes to be set that have a @property decorator

Viewed 139
class MyClass():
   def __init__(self):
      self.attribute_1 = "foo"
      self.attribute_2 = "bar"
 
   @property
   def attribute_1(self):
     return self._attribute_1

   @attribute_1.setter
   def attribute_1(self,s):
     self._attribute_1 = s

   @property
   def attribute_2(self):
     return self._attribute_2

   @attribute_2.setter
   def attribute_2(self,s):
     self._attribute_2 = s

>>> ob = MyClass()
>>> ob.attribute_1 = 'fizz' #Ok
>>> ob.atribute_1 = 'buzz' #want to throw an exception because this has no setter or @property def

I would like my class to complain if we try and set an attribute that has not been decorated with property and a setter. I have tried using slots but can't get it working with the property decorator. 'attribute' in __slots__ conflicts with class variable

Any thoughts?

1 Answers

__slots__ should contain all instance variables, in your case it is _attribute_1 and _attribute_2 (the ones with underscores used internally) so just do that:

class MyClass():
   __slots__ = ["_attribute_1", "_attribute_2"]
   pass # rest of implementation

note that if your property is just directly forwarding you might as well just put the public variables in the slots and only have properties for fields that need more validation or other logic. having slots is effectively a property really:

>>> MyClass._attribute_1
<member '_attribute_1' of 'MyClass' objects>
Related