Say I have a class, which has a number of subclasses.
I can instantiate the class. I can then set its __class__ attribute to one of the subclasses. I have effectively changed the class type to the type of its subclass, on a live object. I can call methods on it which invoke the subclass’s version of those methods.
So, how dangerous is doing this? It seems weird, but is it wrong to do such a thing? Despite the ability to change type at run-time, is this a feature of the language that should completely be avoided? Why or why not?
(Depending on responses, I’ll post a more-specific question about what I would like to do, and if there are better alternatives).
Here’s a list of things I can think of that make this dangerous, in rough order from worst to least bad:
__init__method, so you probably won’t have all of the instance variables initialized properly (or even at all).__slots__, all of the classes must have identical slots. (And if you have the compatible but different slots, it may appear to work at first but do horrible things…)__new__, things will not work the way you naively expected.Meanwhile, in many cases where you’d think this is necessary, there are better options:
__new__or other mechanisms to hook the construction.As a very most common specific case of the last one, just put all of the “variable methods” into classes whose instances are kept as a data member of the “parent”, rather than into subclasses. Instead of changing
self.__class__ = OtherSubclass, just doself.member = OtherSubclass(self). If you really need methods to magically change, automatic forwarding (e.g., via__getattr__) is a much more common and pythonic idiom than changing classes on the fly.