我想在不同的子类中选择一个类,具体取决于输入字典中包含的关键字。 字典看起来像:
{"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或面向对象的方式来做同样的事情? 谢谢!
I want to select a class amongst different children classes, depending on a keyword contained in an input dictionary. The dictionaries look like:
{"car_name": "TeslaS", "electric_engine_name":"X8", "color": "red"}or:
{"car_name": "JaguarXE", "gas_engine_name":"V12", "color": "blue"}And my classes look like this:
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]()I feel that this pattern is not optimal, does anyone know a more pythonic or Object-Oriented way to do the same thing? Thanks!
最满意答案
您可以使用Builder / 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)您可以使用Builder或Factory模式,因为调用者不关心返回什么类实例 ,也不应该关注类依赖性来自何处。
在这个特定的例子中,你只想要一辆车。 你不是特别担心汽车的来源,只是它具有你想要的功能。 因此,如果你想要一辆带有电动引擎的汽车,你可以提供{'electric_engine_name': 'X8'} 。 如果你回来使用TeslaModelS或SomeGuysCustomCar ,甚至SuperCrazyMotorcycle ,你并不担心。 只要它使用X8。 只要它坚持接口,并拥有你感兴趣的引擎。
当然,也许为您提供最好的服务,这个Builder / Factory要求您给它一些其他参数,例如车轮数量,容量,范围,价格等。
在某些情况下,它可以为您提供合理的默认值,但让您自定义它。 这一切只取决于对您的特定情况有意义的事情。
You could use the Builder/Factory pattern:
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)You use the Builder or Factory patterns when you, as the caller do not care what class instance is returned, and also should not be concerned with precisely where the class dependencies come from.
In this particular example, you just want a car. You aren't particularly worried where the car comes from, only that it has the features you want. So if you want a car with an electric engine, you provide {'electric_engine_name': 'X8'}. You're not really worried if you get back a TeslaModelS or SomeGuysCustomCar, or even SuperCrazyMotorcycle. As long as it uses the X8. As long as it adhere's to the interface, and has the engine you're interested in.
Of course, maybe to provide you with the best service, this Builder/Factory requires that you give it some other parameters, such as number of wheels, capacity, range, price, etc.
In some cases it can give you sensible defaults, but let you customize it. It all just depends on what makes sense for your particular situation.
更多推荐
发布评论