在python中

时间:2016-02-02 16:03:06

标签: python oop

我想在不同的子类中选择一个类,具体取决于输入字典中包含的关键字。 字典看起来像:

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

或:

{"car_name": "JaguarXE", "gas_engine_name":"V12", "color": "blue"}

我的课程看起来像这样:

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]()

我觉得这种模式不是最优的,是否有人知道更多的pythonic或面向对象的方式来做同样的事情?谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用Builder /工厂模式:

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)

当您使用Builder或Factory模式时,因为调用者不关心返回什么类实例,并且也不应该关注类依赖性来自何处。

在这个特定的例子中,你只想要一辆车。您并不特别担心汽车来自哪里,只有它具有您想要的功能。因此,如果您想要带有电动引擎的汽车,请提供{'electric_engine_name': 'X8'}。如果您取回TeslaModelSSomeGuysCustomCar,甚至SuperCrazyMotorcycle,您并不担心。只要它使用X8。只要它符合界面,并且拥有您感兴趣的引擎。

当然,也许为您提供最好的服务,这个Builder / Factory要求您给它一些其他参数,例如车轮数量,容量,范围,价格等。

在某些情况下,它可以为您提供合理的默认值,但让您自定义它。这一切只取决于对你的特定情况有意义的事情。

答案 1 :(得分:0)

我想补充一点,你应该在你的dict中有一个额外的属性来存储引擎的类型,而不是迭代密钥找到巧合。