I want to add an attribute to an object which uses slots. I know this is a hack and should not be used.
But is there a way to get around this restriction of slots?
I want to add an attribute to an object which uses slots. I know this is a hack and should not be used.
But is there a way to get around this restriction of slots?
No. If you didn't declare '__dict__'
as one of the slots, then the class has a fixed underlying struct layout with no space for dynamically defined attributes; the best you could do would be to redefine the class from scratch and replace it (and hope no one made an instance of the original before you got to it), or make a subclass (that doesn't have to do anything special in the body, just pass
; if it doesn't declare __slots__
, it will end up with __dict__
/__weakref__
as normal) and use it instead of the parent class.
Even changing __slots__
after the class is defined won't do anything; the slots are baked into the class at that point; you could del MyClass.__slots__
without changing the behavior.
You can kind of modify __slots__
by creating a subclass with the same name and then replacing parent class with its child. Note that you can do this for classes declared and used in any module, not just yours!
Also note that this question has been answered a few times already. See my answer here for more details.
(actually there was no my answer at the time you asked, but there were questions with other answers =)) )
That's exactly what using __slots__
prevents, and it seem you already know this seeing as you've mentioned trying to do what you are doing is a hack you should avoid.
You basically have two options;
Don't use __slots__
. You will be able to add attributes to your hearts content, and depending on how you're using this class you probably won't even notice a performance difference.
Add the attributes up-front, but leave them set to None
(or a sentinal value) and populate them later (instead of creating them later).
If you're trying to make the attributes on your class dynamic - then __slots__
simply isn't the right option for you.