Reputation: 4167
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
Upvotes: 2
Views: 875
Reputation: 730
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...
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.
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.)
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.
Upvotes: 1
Reputation: 77407
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.
Upvotes: 2
Reputation: 12927
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
Upvotes: 1
Reputation: 953
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)
Upvotes: 1