在python中,根据关键字选择要实例化的子类

在python中,根据关键字选择要实例化的子类,python,oop,Python,Oop,我想根据输入字典中包含的关键字,在不同的子类中选择一个类。 这些字典看起来像: {"car_name": "TeslaS", "electric_engine_name":"X8", "color": "red"} 或: 我的课程是这样的: class MotherCarClass(object): motor_keyword = None def __init__(self, *args): super(MotherCarClass, self).__init

我想根据输入字典中包含的关键字,在不同的子类中选择一个类。 这些字典看起来像:

{"car_name": "TeslaS", "electric_engine_name":"X8", "color": "red"}
或:

我的课程是这样的:

class MotherCarClass(object):
    motor_keyword = None
    def __init__(self, *args):
        super(MotherCarClass, self).__init__(*args)


class ElectricCar(MotherCarClass):
    motor_keyword = "electric_engine_name"
    def __init__(self, *args):
        super(ElectricCar, self).__init__(*args)


class GasCar(MotherCarClass):
    motor_keyword = "gas_engine_name"
    def __init__(self, *args):
        super(GasCar, self).__init__(*args)


car_classes = [
    ElectricCar,
    GasCar,
]

def get_car_class_object_from_dict(car_dict):
    """ find the right child class and return an object
    """
    motor_keywords_dict = {car_class.motor_keyword: car_class 
                           for car_class in car_classes}
    for motor_keyword in motor_keywords_dict:
        if motor_keyword in car_dict:
            return motor_keywords_dict[motor_keyword]()
我觉得这种模式不是最优的,有人知道一种更具python风格或面向对象的方法来做同样的事情吗?谢谢

您可以使用/Factory模式:

def build_car(car_info):
    if car_info.get('electric_engine_name') is not None:
        return ElectricCar(**car_info)
    elif car_info.get('gas_engine_name') is not None:
        return InternalCombustionCar(**car_info)
作为调用方,当您不关心返回什么类实例,也不应该关心类依赖项的确切来源时,您可以使用生成器或工厂模式

在这个特殊的例子中,你只想要一辆车。你并不特别担心汽车从哪里来,只担心它有你想要的功能。因此,如果你想要一辆配备电动发动机的汽车,你可以提供
{'electric\u engine\u name':'X8'}
。如果你得到一个
TeslaModelS
SomeGuysCustomCar
,甚至
supercrazimotorcycle
,你就不会真的担心了。只要它使用X8。只要它遵循界面,并且拥有您感兴趣的引擎

当然,为了向您提供最好的服务,该建筑商/工厂要求您提供一些其他参数,如车轮数量、容量、范围、价格等


在某些情况下,它可以为您提供合理的默认值,但允许您自定义它。这一切都取决于你的具体情况。

我想补充的是,你应该在dict中有一个额外的属性来存储发动机的类型,而不是迭代键来寻找一个巧合。

你是真的在做这些汽车类,还是这些舒适感?@Wayne这些是占位符。。。顺便说一句,类只是编码不同行为的一种方式,可以采用不同的方式,只在开始时给出输入字典。字典中的键/值可以定义吗,或者你是否被限制在字典中有不同的键表示你想要不同的行为?@Wayne不,这是不能改变的。首先翻译/规范dict合法吗?如果你这样做了,你可以使用dict访问让你的类与之一起构建-否则我可能会使用我的
If/elif
示例。谢谢你的模式名!
def build_car(car_info):
    if car_info.get('electric_engine_name') is not None:
        return ElectricCar(**car_info)
    elif car_info.get('gas_engine_name') is not None:
        return InternalCombustionCar(**car_info)