tags:

views:

77

answers:

2

Hope this isn't too basic, but...

Suppose I have a base class pa(), and I have derived classes pai(), paj(), etc, that inherit from the base class.

I would like to instantiate an object from base class pa():

>>> from pamod import *
>>> mypa = pa()
>>> mypa
<pamod.pa object at 0x28d4fd0>
>>>

... and then promote it (cast it) to a derived class, based on some action:

>>> mypa.do(this)  
>>> mypa
<pamod.pai object at 0x28d4fd0>
>>>

Where based on the value of "this", mypa becomes an object from class pai, etc.

I know I can assign to the object's __class__.

mypa.__class__ = pai

However I'm wondering if that's really the best approach.

Under my scheme, each instance of pai (say) would have started life as an instance of the base class pa, so pai's __init__ method could be overloaded somehow, I'm guessing.

See this discussion.

Peter

+5  A: 

It's a terrible approach, since you have to handle initialization of the new attributes yourself. Write a class method in the child that returns a new instance with the appropriate attributes copied over.

Ignacio Vazquez-Abrams
Or write your `__init__` so it optionally accepts an instance of the base class.
kindall
+1 This is exactly the right way given the OP's desire.
hughdbrown
+1 DIP is your friend http://en.wikipedia.org/wiki/Dependency_inversion_principle
Juan Mendes
A: 

I don't get it. Seems like reassigning __class__ keeps me from having to copy everything over, which is good since we're talking a huge (100's of MiB) amount of data.

(I'm answering my own question here so I can include code)

What's wrong with this? In reality, "x" and "y" might represent some vast amount of data. Calling mypa.do(1) promotes mypa to a member of class pai:

class pa(object):
    def __init__(self):
        self.x = 1.0

    def do(self,i):
        if i==1:
            self.__class__ = pai
            self.promote()

class pai(pa):
    def __init__(self):
        pa.__init__(self)
        self.promote()

    def promote(self):
        self.y = 2.0
mrentropy