ClassHopper: a wrapper that reevaluates the class of the wrapped instance
    on every access attempt.
    It's like obj.__class__ = callable_returning_a_class(),
    but magically happening before every manipulation with the object.

    Usage: mutant.ClassHopper(initial_object, callable_returning_a_class)

def ClassHopperMutant(initial_object, class_returning_callable, copy=True):
    """
    ClassHopper: a wrapper that reevaluates the class of the wrapped instance
    on every access attempt.
    It's like obj.__class__ = callable_returning_a_class(),
    but magically happening before every manipulation with the object.

    Usage: mutant.ClassHopper(initial_object, callable_returning_a_class)
    """

    from copy import copy as _copy

    def class_mutator(obj):
        obj.__class__ = class_returning_callable(obj)
        return obj

    if copy:
        initial_object = _copy(initial_object)

    return OnAccessMutant(initial_object, class_mutator)