I am writing Python3 code that has different classes who extend a parent class.
I store data in a dictionary and depending of the value of a key I would like to build an object of a type or the other. I have an example here using "if statements":
class Vehicle:
    def __init__(self, d:dict):
        self.color = d["color"]
    def honk(self):
        print("**Abstract honk**")
#attempt at overloading, this function is overwritten later
def buildVehicle( decider:int, d ):
    return Vehicle(d)
class Car(Vehicle):
    def __init__(self, d:dict):
        self.color =        d["color"]
        self.numWheels =    4
        self.isAutomatic =  d["isAutomatic"]
    def honk(self):
        print("Boop boop!")
#attempt at overloading, this function is overwritten later
def buildVehicle( decider:float, d ):
    return Car(d)
class Boat(Vehicle):
    def __init__(self, d:dict):
        self.color =        d["color"]
        self.isCargo =      d["isCargo"]
    def honk(self):
        print("TUUUNNNN TUUUNNNN!")
#attempt at overloading, only this function is considered
def buildVehicle( decider:str, d ):
    return Boat(d)
if __name__=="__main__":
    d = {"type" : "car", "color" : "red", "isAutomatic" : False}
    v = None
    #current implementation
    if d["type"]=="car":
        v = Car(d)
    elif d["type"]=="boat":
        v = Boat(d)
    else:
        v = Vehicle(d)
    #what I would like to do
    ##v = Function( x, y), where Function returns the "correct" type
    ## of Vehicle depending on x, y
    v.honk()
Ideally I would want to get rid of the if-statements. I would like to use a single name to build objects of different types depending of the arguments, such that if a new class is added I do not need to change the existing code. I would be open to modifying the dictionaries to something else.
I tried overloading a method before realizing this was not possible in Python. For context I am a beginner in OOP. I tried looking up my question but I lack the keywords.
