title: How do I downcast in python
body: <p>I have two classes - one which inherits from the other.  I want to know how to cast to (or create a new variable of) the sub class.  I have searched around a bit and mostly 'downcasting' like this seems to be frowned upon, and there are some slightly dodgy workarounds like setting instance.<strong>class</strong> - though this doesn't seem like a nice way to go.</p>
  
  <p>eg.
  <a href="http://www.gossamer-threads.com/lists/python/python/871571" rel="noreferrer">http://www.gossamer-threads.com/lists/python/python/871571</a>
  <a href="http://code.activestate.com/lists/python-list/311043/" rel="noreferrer">http://code.activestate.com/lists/python-list/311043/</a></p>
  
  <p>sub question - is downcasting really that bad?  If so why?</p>
  
  <p>I have simplified code example below - basically i have some code that creates a Peak object after having done some analysis of x, y data.  outside this code I know that the data is 'PSD' data power spectral density - so it has some extra attributes.  How do i down cast from Peak, to Psd_Peak?  </p>
  
  <pre><code>"""
      Two classes
  
  """
  import numpy as np
  
  class Peak(object) :
      """
          Object for holding information about a peak
  
      """
      def __init__(self,
                       index,
                       xlowerbound = None,
                       xupperbound = None,
                       xvalue= None,
                       yvalue= None
                       ):
  
          self.index = index # peak index is index of x and y value in psd_array
  
          self.xlowerbound = xlowerbound
          self.xupperbound = xupperbound
  
          self.xvalue  = xvalue
          self.yvalue  = yvalue
  
  
  
  class Psd_Peak(Peak) :
      """
          Object for holding information about a peak in psd spectrum
  
          Holds a few other values over and above the Peak object.
      """
      def __init__(self,
                       index,
                       xlowerbound = None,
                       xupperbound = None,
                       xvalue= None,
                       yvalue= None,
                       depth = None,
                       ampest = None
                       ):
  
  
          super(Psd_Peak, self).__init__(index,
                                   xlowerbound,
                                   xupperbound,
                                   xvalue,
                                   yvalue)
  
          self.depth = depth
          self.ampest = ampest
  
          self.depthresidual = None
          self.depthrsquared = None
  
  
  
  def peakfind(xdata,ydata) :
      '''
          Does some stuff.... returns a peak.
      '''
  
      return Peak(1,
               0,
               1,
               .5,
               10)
  
  
  
  
  # Find a peak in the data.
  p = peakfind(np.random.rand(10),np.random.rand(10))
  
  
  # Actually the data i used was PSD -
  #  so I want to add some more values tot he object
  
  p_psd = ????????????
  </code></pre>
  
  <hr>
  
  <p><strong>edit</strong></p>
  
  <p>Thanks for the contributions.... I'm afraid I was feeling rather downcast(geddit?) since the answers thus far seem to suggest I spend time hard coding converters from one class type to another.  I have come up with a more automatic way of doing this - basically looping through the attributes of the class and transfering them one to another.  how does this smell to people - is it a reasonable thing to do - or does it spell trouble ahead?</p>
  
  <pre><code>def downcast_convert(ancestor, descendent):
      """
          automatic downcast conversion.....
  
          (NOTE - not type-safe -
          if ancestor isn't a super class of descendent, it may well break)
  
      """
      for name, value in vars(ancestor).iteritems():
          #print "setting descendent", name, ": ", value, "ancestor", name
          setattr(descendent, name, value)
  
      return descendent
  </code></pre>