Assume that we have an object k
of type class A
. We defined a second class B(A)
. What is the best practice to "convert" object k
to class B
and preserve all data in k
?
Asked
Active
Viewed 3.0k times
32

Ivan Chaer
- 6,980
- 1
- 38
- 48

zoli2k
- 3,388
- 4
- 26
- 36
-
2In what way are you looking to convert from one to the other? Do you wish to keep all of the member variables of the class B object, but use the parent class A's set of methods? – BrainCore Jan 28 '10 at 09:04
-
3Is this Pretty Poor Polymorphism? Are A and B subclasses of a common superclass? If so, this is the wrong thing to do? Do you wish that A had the same methods as B? This is done through multiple-inheritance. Please explain why you think you need this because -- in Python -- you're doing it wrong if you think you need casting or type conversion. – S.Lott Jan 28 '10 at 11:52
-
Also really curious about your use case. Is this just for fun, or have you found this to be a better way of adressing some problem, other than with the help of classical polymorphism? – vlad-ardelean Jan 04 '15 at 01:04
-
Depending on your problem, one of [these two methods](http://stackoverflow.com/a/597243/952580) for achieving a similar result might be suitable, without feeling like a hack. – Beetle Jan 13 '15 at 16:45
3 Answers
20
This does the "class conversion" but it is subject to collateral damage. Creating another object and replacing its __dict__
as BrainCore posted would be safer - but this code does what you asked, with no new object being created.
class A(object):
pass
class B(A):
def __add__(self, other):
return self.value + other
a = A()
a.value = 5
a.__class__ = B
print a + 10

jsbueno
- 99,910
- 10
- 151
- 209
8
a = A() # parent class
b = B() # subclass
b.value = 3 # random setting of values
a.__dict__ = b.__dict__ # give object a b's values
# now proceed to use object a
Would this satisfy your use case? Note: Only the instance variables of b will be accessible from object a, not class B's class variables. Also, modifying variables in a will modify the variable in b, unless you do a deepcopy:
import copy
a.__dict__ = copy.deepcopy(b.__dict__)

BrainCore
- 5,214
- 4
- 33
- 38
-
1Actually, no variables will be copied. Since `a` and `b` now both share the same `__dict__`, setting `a.value` changes `b.value` too. – Robert Rossney Jan 28 '10 at 10:08
-
Actually on doing this, the "a" object should be destroyed immediately. Else one does end up with two different objects, in different classes sharing the same attributes - there are few worse scenarios than this. (It is scary to play around even at the interactive prompt) – jsbueno Nov 25 '14 at 16:28
2
class A:
def __init__(self, a, b):
self.a = a
self.b = b
class B(A):
def __init__(self, parent_instance, c):
# initiate the parent class with all the arguments coming from
# parent class __dict__
super().__init__(*tuple(parent_instance.__dict__.values()))
self.c = c
a_instance = A(1, 2)
b_instance = B(a_instance, 7)
print(b_instance.a + b_instance.b + b_instance.c)
>> 10
Or you could have a sperate function for this:
def class_converter(convert_to, parent_instance):
return convert_to(*tuple(parent_instance.__dict__.values()))
class B(A):
def __init__(self, *args):
super().__init__(*args)
self.c = 5
But using the 2nd method, I wasn't able to figure out how to pass additional values

Yaniv K.
- 237
- 4
- 12