Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Initially I've supplied an answer which is based on changing <code>self.__class__</code> during <code>__init__()</code>. It was explained to me in the comments that this should be avoided.</p> <p>Now I am providing an answer that that is based on redefining the base class' <code>__new__</code>:</p> <pre><code>class Car(object): """The base class.""" def __new__(cls, max_speed): if cls is Car and max_speed &gt; 100: return object.__new__(SuperCar, max_speed) else: return object.__new__(cls, max_speed) def __init__(self, max_speed): self.max_speed = max_speed class SuperCar(Car): """The sub class.""" pass </code></pre> <p>The code responsible for the creation of an instance is in the built in(1) <code>__new__</code> method. It is called when a class is called (e.g. <code>my_car = Car(100)</code>) and passed the arguments that were given in that call.</p> <p>When the instanciation of a <code>Car</code> or a <code>SuperCar</code> (due to the inheritance of <code>__new__</code>) is called, the redefined <code>__new__</code> checks whether the instance to be created is of <code>cls</code> <code>Car</code> and also has a <code>max_speed</code> greater than 100.</p> <p>If so, it creates an instance of <code>SuperCar</code>, instead of <code>Car</code>, using <code>object.__new__(SuperCar, max_speed)</code> and returns that.</p> <p>Otherwise, it calls upon the normal, default, built in, <code>__new__</code> for the creation of this instance, using <code>object.__new__(cls, max_speed)</code> and returns that. This catches the expected case where <code>not max_speed &gt; 100</code> and also the case where this redefined <code>__new__</code> is called by the subclass <code>SuperCar</code> (like in <code>my_ferrari = SuperCar(250)</code>).</p> <p>For the record, here's my former answer:</p> <blockquote> <p>When you want an instance's class to be changed to one of it's subclasses, depending on some condition, upon creation of that instance, you can use some logic in <code>__init__</code>, like so:</p> <pre><code>class Car(object): def __init__(self, max_speed_kph): if self.__class__ == Car: if max_speed_kph &gt; 230: self.__class__ = SuperCar self.__init__() class SuperCar(Car): def __init__(self): print 'this car is fast!' </code></pre> <p>The <code>self.__init__()</code> is for re-initialisation of the instance as it's new class.</p> </blockquote> <p>Footnotes:</p> <ol> <li>Is this really a built-in? I can't see it in the "Built-in functions" topic of Python Documentation.</li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload