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

Community
  • 1
  • 1
mrentropy
  • 57
  • 1
  • 3

2 Answers2

4

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
  • 776,304
  • 153
  • 1,341
  • 1,358
  • Or write your `__init__` so it optionally accepts an instance of the base class. – kindall Oct 29 '10 at 01:53
  • +1 DIP is your friend http://en.wikipedia.org/wiki/Dependency_inversion_principle – Ruan Mendes Oct 29 '10 at 20:46
  • It would be a good way of monkey patching an object to add methods. `1.` Derive the class of the object and add some methods. `2.` Promote the object – nadapez Jan 21 '23 at 18:09
0

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
  • 57
  • 1
  • 3