I have this class which uses slots and descriptors.
I put the name of the variables in __slots__
and use descriptors to set their values.
class Example:
__slots__ = ('__x', '__y') #see the double undescores
_x = descriptor_of_x()
_y = descriptor_of_y()
def __init__(self, x, y):
self._x = x
self._y = y
The descriptors look like this.
class descriptor_of_x:
__slots__ = ('name')
def __set_name__(self, owner, name):
# the name of the variable that will be set is
# the name of the variable that called it prepended with a underscore.
self.name = f"_{name}"
def __set__(self, obj, value):
setattr(obj, self.name, value)
def __get__(self, obj, objtype=None):
return getattr(obj, self.name)
When I run this I get:
'Example' object has no attribute '__x'
when I remove the __slots__
and then use vars()
on the instance for Example,
I can clearly see __x
and __y
in the resulting dict.
So, the names are correct, I definitely put them in the slots but it can't find them.
What am I missing here? Are the variables being declared before __slots__
is?
from te docs:
the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam
When the slots is created, the items with the double underscores get renamed, that is why they can't be found.
changed the desciptors to append an underscore instead of prepend and now the variables in slots should be _x_ and _y_, this now works.