How do I downcast in python

upcasting in python
typecasting in python
typecase python
type coercion python
python inheritance downcast
python implicit cast
python type juggling
python dynamic type casting

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.class - though this doesn't seem like a nice way to go.

eg. http://www.gossamer-threads.com/lists/python/python/871571 http://code.activestate.com/lists/python-list/311043/

sub question - is downcasting really that bad? If so why?

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?

"""
    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 = ????????????

edit

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?

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

You don't actually "cast" objects in Python. Instead you generally convert them -- take the old object, create a new one, throw the old one away. For this to work, the class of the new object must be designed to take an instance of the old object in its __init__ method and do the appropriate thing (sometimes, if a class can accept more than one kind of object when creating it, it will have alternate constructors for that purpose).

You can indeed change the class of an instance by pointing its __class__ attribute to a different class, but that class may not work properly with the instance. Furthermore, this practice is IMHO a "smell" indicating that you should probably be taking a different approach.

In practice, you almost never need to worry about types in Python. (With obvious exceptions: for example, trying to add two objects. Even in such cases, the checks are as broad as possible; here, Python would check for a numeric type, or a type that can be converted to a number, rather than a specific type.) Thus it rarely matters what the actual class of an object is, as long as it has the attributes and methods that whatever code is using it needs.

How do I downcast in python, 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  Is there a way to downcast the swig proxy of a swig object on the fly? The reason for doing this is to emulate C++ downcasting, but purely from python. For example, typical C++ usage would be MyB

This isn't a downcasting problem (IMHO). peekfind() creates a Peak object - it can't be downcast because its not a Psd_Peak object - and later you want to create a Psd_Peak object from it. In something like C++, you'd likely rely on the default copy constructor - but that's not going to work, even in C++, because your Psd_Peak class requires more parameters in its constructor. In any case, python doesn't have a copy constructor, so you end up with the rather verbose (fred=fred, jane=jane) stuff.

A good solution may be to create an object factory and pass the type of Peak object you want to peekfind() and let it create the right one for you.

def peak_factory(peak_type, index, *args, **kw):
    """Create Peak objects

    peak_type     Type of peak object wanted
       (you could list types)
    index         index
       (you could list params for the various types)
    """
    # optionally sanity check parameters here
    # create object of desired type and return
    return peak_type(index, *args, **kw)

def peakfind(peak_type, xdata, ydata, **kw) :
    # do some stuff...
    return peak_factory(peak_type, 
         1,
         0,
         1,
         .5,
         10,
         **kw)

# Find a peak in the data.
p = peakfind(Psd_Peak, np.random.rand(10), np.random.rand(10), depth=111, ampest=222)

Downcast Numerical Data Types with Pandas, Using an Example Where We Downcast Numerical Columns. by using strict types (instead of normal Python "duck typing"), you can do things  To do this, I've written into the swig .i file a helper function in c++ which does the down-casting: %inline %{ Derived* CastToDerived(Base* base) { return static_cast<Derived*>(base); } %} In my python code, I call this down-casting function: base = container.GetBase() derived = CastToDerived(base) When I do so, I get the following error:

See following example. Also, be sure to obey the LSP (Liskov Substitution Principle)

class ToBeCastedObj:
    def __init__(self, *args, **kwargs):
        pass  # whatever you want to state

    # original methods
    # ...


class CastedObj(ToBeCastedObj):
    def __init__(self, *args, **kwargs):
        pass  # whatever you want to state

    @classmethod
    def cast(cls, to_be_casted_obj):
        casted_obj = cls()
        casted_obj.__dict__ = to_be_casted_obj.__dict__
        return casted_obj

    # new methods you want to add
    # ...

NumPy: Upcasting, In NumPy and in Python, upcasting is done implicitly. So, let's take a quick look at an example. We'll start with an array containing five integers and then create a  Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question. Provide details and share your research! But avoid … Asking for help, clarification, or responding to other answers. Making statements based on opinion; back them up with references or personal experience. To learn more, see our tips on writing great

Downcast (I know it sounds silly, but ), I was wondering if it is possible in Python to do something analogous to downcasting in a statically typed language like C++. I mean is it possible to take an  According to my experiments, it's possible to downcast to integer values like. pd.to_numeric(pd.Series([1.0, 2.0]), downcast='unsigned') 0 1 1 2 dtype: uint8 Though, it's not possible to downcast to integer values like. pd.to_numeric(pd.Series([1.1, 2.1]), downcast='unsigned') 0 1.1 1 2.1 dtype: float64

How do I downcast in python, downcasting in python typecasting in python python cast to class typecase python type coercion python python implicit cast python cast object to subclass python  Converting one data type to others in Java is known as casting. Up casting − If you convert a higher datatype to lower datatype, it is known as narrowing (assigning higher data type value to the lower data type variable).

Python Type Conversion and Type Casting (With Examples), The process of converting the value of one data type (integer, string, float, etc.) to another data type is called type conversion. Python has two types of type  C:\Users\Pattis\AppData\Local\Programs\Python\Python37\python.exeappears, and inside the window; on the first line is the text (notice that it should also say 64 bit). exit()to this prompt and press enterto terminate Python. You should keep the file python-3.7.4.exesomewhere on your computer in

Comments
  • why downcast? At some point you were able to create an instance of the base class! Why not create an instance of the derived class from the beginning?
  • I guess the main motivation would be laziness, combined with a sense that OO is supposed to make things easier in the long run - by planning of data structures. In some senses by saying that B is a subclass of A surely python should be able to meld from one to the other without me hardcoding it? - Or is that unreasonable? Suppose i have a base class with many subclasses. OO would make you think that a change to the base class wouldn't require changes to the subclasses - but in your way it would.
  • Think Duck Typing. If it quacks like a Psd_Peak (that is, it has Psd_Peak methods) it is a Psd_Peak. The method you want is sitting right there on the variable. Just call it. You can use isinstance(Psd_Peak) or hasattr(myvar, 'my_method') or just call it and catch AttributeError for when you guess wrong.
  • I like the duck typing idea. Unfortunately it doesn't really solve my problem. In essence what I'm asking is how do I stick a beak onto my animal to make it into a duck....
  • Why not just make peakfind return a Psd_Peak?
  • Thanks for the clarification. I guess in a sense i don't mind if the process is one of 'casting' or 'converting'. My contention though is that it should be something that is possible automagically by python - to a disinterested person, the fact that I've defined one class as a subtype of the other should give python almost everything it needs to do this. Other point about 'converting'/'casting'...for large objects would this not be incredibly wasteful?
  • This isn't something that could be done automatically. Suppose you convert an instance to its parent class after initializing it. But the subclass has changed the meaning of a key attribute, or accepts a wider range of values for the attribute than does the base class. The base methods might not be able to make sense of the data in the subclass instance's attributes. How is Python supposed to know that?
  • To address your second question, yes it could be time-consuming for large objects. Fortunately you hardly ever need to do it. In any case, if performance were that important, you wouldn't be using Python.
  • One reason way you may care about types is Pickling. Some C++ objects that are marshalled in python may not pickle correctly, so you may have a type system that allows you to downcast to avoid the C++ objects before pickling
  • Thanks for the suggestion. I guess I'm not entirely happy with it though - since it requires 'peakfind' which should be pretty general to know what type of data it is working on... Seems nicer to have a downcast (or conversion) or whatever after the fact. You are right that Peak isn't a Psd_Peak - BUT Psd_Peak is a Peak - therefore there is a simple transform to it - I was just surprised that python hadn't provided it. Since it is written by people much clever than me, it presumably is a design decision rather than an omission?
  • ** Actually your answer has got me thinking - I guess i could make peakfind take the actual constructor as an argument - then it could do its stuff on the object, not knowing if it is a Peak, or a Psd_Peak, or a Foo_Peak etc.
  • @JPH yeah, that's pretty much what the example does. Follow the steps through and you'll see that the factory is calling Psd_Peak's init implicitly when instatiating the class.