32

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?

4
  • 2
    In 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? Commented Jan 28, 2010 at 9:04
  • 3
    Is 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. Commented Jan 28, 2010 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? Commented Jan 4, 2015 at 1:04
  • Depending on your problem, one of these two methods for achieving a similar result might be suitable, without feeling like a hack. Commented Jan 13, 2015 at 16:45

3 Answers 3

21

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
Sign up to request clarification or add additional context in comments.

Comments

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__)

2 Comments

Actually, no variables will be copied. Since a and b now both share the same __dict__, setting a.value changes b.value too.
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)
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.