2

A bit of an odd question, but I'm wondering how to import an object from one class to another. I imagine adding more class methods and attributes as I expand my program, and I still want to be able to use old data. I am thinking something as follows:

class old_obj:

    def __init__(self, text):
        self.name = text

    def set_amount(self, num):
        self.amount = num

    def introduce_yourself(self):
        print("I am {} and I am {} many".format(self.name, self.amount))

oldest = old_obj("myself")
oldest.set_amount(15)
also_old = old_obj("Bach")

class new_obj:
    def __init__(self):
        #some code
    #more code

I want to be able to write something like:

renewed = new_obj(oldest)
also_new = new_obj(also_old)

Here, I want to retain the 15 from oldest.amount, but not complain that also_old.amount is None. In particular, I want to retain any attributes that oldest has, while not requiring that it have all possible attributes. Is there a way for me to copy over instances of a class to a new class?

Edit: edited for clarity

1
  • Why not extending it? class new_obj(old_obj):. Commented May 24, 2020 at 22:14

4 Answers 4

2

You could copy the object instance dict to the new class.

from copy import deepcopy

class old_obj:

    def __init__(self, text):
        self.name = text

    def set_amount(self, num):
        self.amount = num

    def introduce_yourself(self):
        print("I am {} and I am {} many".format(self.name, self.amount))

oldest = old_obj("myself")

class new_obj:
    def __init__(self, my_old_obj):
        for var, val in my_old_obj.__dict__.items():
            setattr(self, var, deepcopy(val))
        #some code
    #more code

newest = new_obj(oldest)

I did a deepcopy of the value assuming you want unique values in the new object. But that can also be problematic because not everything can be copied (file objects for instance). There can be other oddities when duplicating attributes such as what you want to do with a generator. And if this is something like a GUI widget, it could get stranger still.

But for a lot of object types, this would work.

Sign up to request clarification or add additional context in comments.

1 Comment

This looks much more like what I'm looking for. I guess if I combine this with the answer from @Błotosmętek I can set new objects by either passing in an old one, or by passing in a string. I think this solves my problem, thanks!
1

Slightly different take:

Your new class has a set of concerns that are probably similar to your old class. This should guide the way you update it and build out the behavior in question. With this in mind...

  1. Provide a class method in your new class to allow construction of the new object from the old object. Don’t make this behavior a part of __init__. Your __init__ should have a more limited responsibility. For the class method, updating the new object’s __dict__ using the old object’s __dict__ would do the job.

  2. Don’t use inheritance to make new versions of classes. Use inheritance to move from general to specific or abstract to concrete. Otherwise, you end up with code that is hard to understand and update. (Imagine several generations down of just sub-classing in order to add some new methods.)

  3. If the number of methods and attributes is growing, you might want to consider whether or not you’re encapsulating data/behaviors that should be split into multiple classes. The guiding principle is that you should encapsulate the data/behaviors that are likely to change together. That is, when you change the way you’re implementing your program, things that don’t need to change should probably be encapsulated separate from things that need changing. If you find that a lot of your static data is bound up with an object class that you’re frequently updating (but wanting to just import the old data unchanged), then you’ve probably got two different sets of concerns, at least.

Comments

1

You can simply initialize the new object by passing it the old one.

class old_obj:
    def __init__(self, text):
        self.text = text

oldest = old_obj("myself")

class new_obj:
    def __init__(self, old_inst):
        self.text = old_inst.text 

renewed = new_obj(oldest)

print(renewed.text)

3 Comments

I'm not sure if I was clear and specific enough, but I need in particular to be able to scale the instantiation based on how many attributed the original object has. I'm gonna edit my original question to make this clearer.
@Mathchiller - This scales... with a bit of typing.
The point is, I want to be able to plug in old objects, some of which have all their attributes set, and some which don't. I'd like to retain all the info they have, while simultaneously not requiring it.
1

First, make your new_obj class inherit from old_obj, so that new_obj has all the methods old_obj had:

class new_obj(olb_obj):

Then, in __init__ method of the new class you can check what is passed as the argument - a string or an object:

    def __init__(self, arg):
        if isinstance(arg, str):
            self.text = arg
        elif isinstance(arg, old_obj):
            self.text = arg.text 
        else:
            raise TypeError

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.