Python object conversion

Question:

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 By: zoli2k

||

Answers:

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__)
Answered By: BrainCore

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
Answered By: jsbueno
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

Answered By: Yaniv K.
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.