Python: is there a use case for changing an instance's class?

object, python

Solution

There is rarely a good reason to do this for unrelated classes, like `Robe` and `Dress` in your example. Without a bit of work, it's hard to ensure that the object you get in the end is in a sane state.

However, it can be useful when inheriting from a base class, if you want to use a non-standard factory function or constructor to build the base object. Here's an example:

class Base(object):
    pass

def base_factory():
    return Base()  # in real code, this would probably be something opaque

def Derived(Base):
    def __new__(cls):
        self = base_factory()     # get an instance of Base
        self.__class__ = Derived  # and turn it into an instance of Derived
        return self

In this example, the Derived class's `__new__` method wants to construct its object using the `base_factory` method which returns an instance of the `Base` class. Often this sort of factory is in a library somewhere, and you can't know for certain how it's making the object (you can't just call `Base()` or `super(Derived, cls).__new__(cls)` yourself to get the same result).

The instance's `__class__` attribute is rewritten so that the result of calling `Derived.__new__` will be an instance of the `Derived` class, which ensures that it will have the `Derived.__init__` method called on it (if such a method exists).

Problem

Related: Python object conversion I recently learned that Python allows you to change an instance's class like so: ``` class Robe: pass class Dress: pass r = Robe() r.__class__ = Dress ``` I'm trying to figure out whether there is a case where 'transmuting' an object like this can be useful. I've messed around with this in IDLE, and one thing I've noticed is that assigning a different class doesn't call the new class's `__init__` method, though this can be done explicitly if needed. Virtually every use case I can think of would be better served by composition, but I'm a coding newb so what do I know. ;)

Original source