There is a base class Base
and a subclass Special
.
class Base(object):
def __init__(self, name):
self.name = name
d
actually you can, but I don't think you should. instead of typecasting python has duck-typing to solve this kind of situation.
anyway, here's the code:
>>> base = Base("I'm a base!")
>>> hasattr(base, 'rhyme')
False
>>> base.__class__ = Special
>>> hasattr(base, 'rhyme')
True
>>> base.rhyme()
"Hi I'm a base!! How are you? Fine, thanks. What about you?"
You can achieve this by defining an alternate constructor and reassigning the instance's __class__
attribute.
class Base(object):
def __init__(self, name):
self.name = name
def greet(self):
return 'Hello %s' % self.name
@classmethod
def alt_constructor(cls, *args, **kwargs):
obj = cls(*args, **kwargs)
obj.__class__ = Special
return obj
class Special(Base):
def __init__(self, name):
super(Special, self).__init__(name)
def rhyme(self):
return 'Hi %s! How are you? Fine, thanks. What about you?' % self.name
>>> s = Base.alt_constructor("test")
>>> print s.rhyme()
Hi test! How are you? Fine, thanks. What about you?
EDIT:
Moved the constructor from Special
to Base
.
If you can't modify the Base
class you can add a classmethod to Special
that will change the class of any object passed to it.
class Base(object):
def __init__(self, name):
self.name = name
def greet(self):
return 'Hello %s' % self.name
class Special(Base):
def __init__(self, name):
super(Special, self).__init__(name)
def rhyme(self):
return 'Hi %s! How are you? Fine, thanks. What about you?' % self.name
@classmethod
def convert_to_special(cls, obj):
obj.__class__ = Special
>>> b = Base("test")
>>> print type(b)
<class '__main__.Base'>
>>> Special.convert_to_special(b)
>>> print type(b)
<class '__main__.Special'>
A more all purpose solution would be to create a mixin that can be added to any class.
class ConverterMixin(object):
@classmethod
def convert_to_class(cls, obj):
obj.__class__ = cls
class Special(ConverterMixin, Base):
def __init__(self, name):
super(Special, self).__init__(name)
def rhyme(self):
return 'Hi %s! How are you? Fine, thanks. What about you?' % self.name
>>> b = Base("test")
>>> print type(b)
<class '__main__.Base'>
>>> Special.convert_to_class(b)
>>> print type(b)
<class '__main__.Special'>