根据条件将请求传递给不同的类

时间:2020-04-02 12:30:58

标签: python

我正在设计一种API,用于处理不同类型的车辆,例如汽车,公共汽车和厢式货车。有一个端点POST /vehicle,它将采用已定义的主体。

{
'registration': 'str',
'date_of_purchase': 'datetime str',
'vehicle_type': 'car'
...
}

我们要做的第一件事是基于vehicle_type加载对象。

if body[vehicle_type] == 'car':
   passed_in_vehicle = Car(body)
elif body['vehicle_type'] == 'bus':
   passed_in_vehicle = Bus(body)
...

在python程序中,有多个类,包括:

  • vehicles.py
  • cars.py
  • vans.py
  • buss.py

API入口点进入Vehicles.py,它执行一些逻辑,然后根据输入将其路由到其他类之一以执行更具体的逻辑。

每个类都具有相同的基本方法集。

  • update_vehicle_specs
  • register_vehicle

此刻我在Vehicles.py的底部

if is_instance(passed_in_vehicle, Car):
   carService = Cars()
   carService.register_vehicle(passed_in_vehicle)
elif is_instance(passed_in_vehicle, Van):
   vanService = Vans()
   vanService.register_vehicle(passed_in_vehicle)
...

但是,这不能扩展。根据条件路由到特定类的正确解决方案是什么?

2 个答案:

答案 0 :(得分:2)

我不知道使用本地语言是否理想,但至少我相信它会比您当前的解决方案更好地扩展

  • 使用字符串名称从内置的locals()实例化类,该类会将导入存储为字典
class Car(object):
    def print(self):
        print("I'm a car")
class Bus(object):
    def print(self):
        print("I'm a bus")

vehicle_type = "Car"
currV_class = locals()[vehicle_type]
currV_instance = currV_class()
#currV_instance.register_vehicle
currV_instance.print()

vehicle_type = "Bus"
currV_class = locals()[vehicle_type]
currV_instance = currV_class()
#currV_instance.register_vehicle
currV_instance.print()

输出:

I'm a car
I'm a bus

答案 1 :(得分:2)

在我看来,您可以改进设计。由于每辆车都会“知道”其维修地点,因此您可能应该在类似的地方进行

def __init__(self, ..., service):
    super().__init__(self, ...)
    ...
    ...
    service.register_vehicle(self)

这是从“汽车驶入车库进行登记”而不是“车库寻找新车”的角度出发的。

初始化车辆时,将其维修等级传递给它,如

new_car = Car(..., my_car_service)

其中

my_car_service = Cars()

之前的某个地方。这是因为我们假设每辆新车都需要注册,并且我们不为每辆新车提供新服务。另一种方法是让类从一开始就包含(组成)其服务对象:

class Car:
    service = Cars()
    def __init__(...)
        ...
        Car.service.register_vehicle(self)

因此,该类始终包含服务对象,并且所有初始化的对象都通过类变量共享同一对象。我实际上更喜欢这个。


第一次初始化:

关于车辆的初始初始化,虽然使用locals可能是一个不错的解决方案,但拥有类似您的物品可能更安全一些。在Python中,我喜欢使用“ Python转换字典”(TM)来实现以下目的:

{'car': Car,
 'bus': Bus,
  ...
 'jet': Jet
}[body[vehicle_type]](body)