简体   繁体   中英

How to create a subclass instance from a superclass instance

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM