I would like to create a subclass instance from a superclass instance in Python. Suppose I have something like this:
class A():
def __init__(self, type):
...
self.type = type # this will be something that corresponds to either B or C
class B(A):
def do_something():
# this method is subclass specific
class C(A):
def do_something():
# this method is again subclass specific
I have a function that receives an instance of A, and I need to create an instance of either B or C (or D ...) based on what A's attribute type
is.
I'm not sure how to go about this. Is there a way out of this or does the solution need to be redesigned?
Thank you
Use a dictionary that maps from types to classes.
class A():
typemap = {}
def __init__(self, typearg): # renamed this argument so it doesn't shadow standard type() function
self.type = typearg
self.typemap[typearg] = type(self)
def create_child(self, *args):
return typemap[self.type](*args)
When the constructor runs, type(self)
gets the subclass of the object being created. This is then stored in the dictionary, so we can look it up using self.type
.
The create_child()
looks up the class in the dictionary, and calls it to create a new instance of that child class.
Start by redefining the classes A, B and C as follows. Note that you also need to pass the type
value from subclass to superclass constructor via super().__init__()
class A():
def __init__(self, type):
...
self.type = type # this will be something that corresponds to either B or C
class B:
def __init__(self, type):
super().__init__(type)
def do_something(self):
print('do_something called for B')
class C:
def __init__(self, type):
super().__init__(type)
def do_something(self):
print('do_something called for C')
Then make another class which can make the decision whether to call B and C for you, and save that object locally
class User:
def __init__(self, type):
self.obj = None
if type == 'B':
self.obj = B(type)
elif type == 'C':
self.obj = C(type)
Then you can instantiate user class with different types and see that the correct do_something
is called.
user_B = User('B')
user_B.obj.do_something()
#do_something called for B
user_C = User('C')
user_C.obj.do_something()
#do_something called for C
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.