title: Reclassing an instance in Python
body: <p>I have a class that is provided to me by an external library. I have created a subclass of this class. I also have an instance of the original class.</p>
  
  <p>I now want to turn this instance into an instance of my subclass without changing any properties that the instance already has (except for those that my subclass overrides anyway).</p>
  
  <p>The following solution seems to work.</p>
  
  <pre><code># This class comes from an external library. I don't (want) to control
  # it, and I want to be open to changes that get made to the class
  # by the library provider.
  class Programmer(object):
      def __init__(self,name):
          self._name = name
  
      def greet(self):
          print "Hi, my name is %s." % self._name
  
      def hard_work(self):
          print "The garbage collector will take care of everything."
  
  # This is my subclass.
  class C_Programmer(Programmer):
      def __init__(self, *args, **kwargs):
          super(C_Programmer,self).__init__(*args, **kwargs)
          self.learn_C()
  
      def learn_C(self):
          self._knowledge = ["malloc","free","pointer arithmetic","curly braces"]
  
      def hard_work(self):
          print "I'll have to remember " + " and ".join(self._knowledge) + "."
  
      # The questionable thing: Reclassing a programmer.
      @classmethod
      def teach_C(cls, programmer):
          programmer.__class__ = cls # &lt;-- do I really want to do this?
          programmer.learn_C()
  
  
  joel = C_Programmer("Joel")
  joel.greet()
  joel.hard_work()
  #&gt;Hi, my name is Joel.
  #&gt;I'll have to remember malloc and free and pointer arithmetic and curly braces.
  
  jeff = Programmer("Jeff")
  
  # We (or someone else) makes changes to the instance. The reclassing shouldn't
  # overwrite these.
  jeff._name = "Jeff A" 
  
  jeff.greet()
  jeff.hard_work()
  #&gt;Hi, my name is Jeff A.
  #&gt;The garbage collector will take care of everything.
  
  # Let magic happen.
  C_Programmer.teach_C(jeff)
  
  jeff.greet()
  jeff.hard_work()
  #&gt;Hi, my name is Jeff A.
  #&gt;I'll have to remember malloc and free and pointer arithmetic and curly braces.
  </code></pre>
  
  <p>However, I'm not convinced that this solution doesn't contain any caveats I haven't thought of (sorry for the triple negation), especially because reassigning the magical <code>__class__</code> just doesn't feel right. Even if this works, I can't help the feeling there should be a more pythonic way of doing this.</p>
  
  <p>Is there?</p>
  
  <hr>
  
  <p>Edit: Thanks everyone for your answers. Here is what I get from them:</p>
  
  <ul>
  <li><p>Although the idea of reclassing an instance by assigning to <code>__class__</code> is not a widely used idiom, most answers (4 out of 6 at the time of writing) consider it a valid approach. One anwswer (by ojrac) says that it's "pretty weird at first glance," with which I agree (it was the reason for asking the question). Only one answer (by Jason Baker; with two positive comments &amp; votes) actively discouraged me from doing this, however doing so based on the example use case moreso than on the technique in general.</p></li>
  <li><p>None of the answers, whether positive or not, finds an actual technical problem in this method. A small exception is jls who mentions to beware of old-style classes, which is likely true, and C extensions. I suppose that new-style-class-aware C extensions should be as fine with this method as Python itself (presuming the latter is true), although if you disagree, keep the answers coming.</p></li>
  </ul>
  
  <p>As to the question of how pythonic this is, there were a few positive answers, but no real reasons given. Looking at the Zen (<code>import this</code>), I guess the most important rule in this case is "Explicit is better than implicit." I'm not sure, though, whether that rule speaks for or against reclassing this way.</p>
  
  <ul>
  <li><p>Using <code>{has,get,set}attr</code> seems more explicit, as we are explicitly making our changes to the object instead of using magic.</p></li>
  <li><p>Using <code>__class__ = newclass</code> seems more explicit because we explicitly say "This is now an object of class 'newclass,' expect a different behaviour" instead of silently changing attributes but leaving users of the object believing they are dealing with a regular object of the old class.</p></li>
  </ul>
  
  <p>Summing up: From a technical standpoint, the method seems okay; the pythonicity question remains unanswered with a bias towards "yes." </p>
  
  <p>I have accepted Martin Geisler's answer, because the Mercurial plugin example is a quite strong one (and also because it answered a question I even hadn't asked myself yet). However, if there are any arguments on the pythonicity question, I'd still like to hear them. Thanks all so far.</p>
  
  <p>P.S. The actual use case is a UI data control object that needs to grow additional functionality <em>at runtime</em>. However, the question is meant to be very general.</p>