我想在不同的子类中选择一个类,具体取决于输入字典中包含的关键字。 字典看起来像:
{"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或面向对象的方式来做同样的事情?谢谢!
答案 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'}
。如果您取回TeslaModelS
或SomeGuysCustomCar
,甚至SuperCrazyMotorcycle
,您并不担心。只要它使用X8。只要它符合界面,并且拥有您感兴趣的引擎。
当然,也许为您提供最好的服务,这个Builder / Factory要求您给它一些其他参数,例如车轮数量,容量,范围,价格等。
在某些情况下,它可以为您提供合理的默认值,但让您自定义它。这一切只取决于对你的特定情况有意义的事情。
答案 1 :(得分:0)
我想补充一点,你应该在你的dict中有一个额外的属性来存储引擎的类型,而不是迭代密钥找到巧合。