如何在 Python 中为不同的硬件驱动程序创建可扩展的软件模型?

How to create an extendable software model for different hardware drivers in Python?

我必须为不同的硬件驱动程序概念化一个软件模型。所讨论的硬件是具有相同核心功能但不同附加功能的测量仪器。驱动程序以及使用驱动程序的脚本在 Python 中编程。通过保持几乎相同的脚本来替换使用过的硬件应该很容易。更换硬件时,对脚本的必要更改应该最少。

因此,对于所有不同的硬件驱动程序,核心模型必须相同,以便仅使用硬件核心功能的脚本独立于实际连接的硬件。这很容易通过继承解决。

但是,对于仅受某些仪器支持而其他仪器不支持的功能,如何解决这个问题呢?让我们以下面的代码为例:

class BaseDriver:
   def coreFunctionA(self):
      pass
   def coreFunctionB(self):
      pass

class DriverModelA(BaseDriver):
   def coreFunctionA(self):
      pass
   def coreFunctionB(self):
      pass

   def additionalFunctionX(self):
      pass
   def additionalFunctionY(self):
      pass

class DriverModelB(BaseDriver):
   def coreFunctionA(self):
      pass
   def coreFunctionB(self):
      pass

   def additionalFunctionX(self):
      pass

class DriverModelC(BaseDriver):
   def coreFunctionA(self):
      pass
   def coreFunctionB(self):
      pass

   def additionalFunctionY(self):
      pass

BaseDriver 中总结了所有仪器型号都相同的核心功能。但是如何处理仅由某些驱动程序支持的功能(如 "additionalFunctionX" 和 "additionalFunctionY")?如果 DriverModelA 和 DriverModelB 中的函数 additionalFunctionX 做同样的事情,它们应该有相同的签名,这样接口更容易被用户理解。我可以将这些函数也放入基 class 中,并为所有不支持此功能的驱动程序抛出异常。但在我看来,那将是非常难看的代码。

那么你们知道如何将这些附加功能组合在一起吗?我想避免为每个驱动程序以不同的方式实现相同的功能。如果驱动程序支持某些其他驱动程序也支持的特定功能,则此功能也应该具有相同的调用语义或所有驱动程序的相同接口。

您可以创建多个 "mixin" 类:

class Base():
    def base_func(self):
        print('Base func')

class Speedometer():
    def read_speedometer(self):
        print('Speedometer')

class Gyroscope():
    def read_gyroscope(self):
        print('Gyroscope')

并将它们添加到您需要的任何地方:

class Implementation1(Base):
    pass

class Implementation2(Base, Speedometer):
    pass

class Implementation3(Base, Speedometer, Gyroscope):
    pass


impl1 = Implementation1()
impl2 = Implementation2()
impl3 = Implementation3()

impl1.base_func()
impl2.read_speedometer()
impl3.read_speedometer()
impl3.read_gyroscope()

创建具有重复函数的混入时必须小心,但有一些解决方法:

class Duplicate():
    def read_speedometer(self):
        print('duplicate')

class Implementation4(Base, Speedometer, Duplicate):
    def read_duplicate(self):
        Duplicate.read_speedometer(self)

impl4 = Implementation4()
impl4.read_speedometer()  # >>> 'speedometer'
impl4.read_duplicate()  # >>> 'duplicate'

通常建议使用组合而不是继承,正如许多以 GoF 开头的书籍所推荐的那样。

我会说:

class YDriver:
    def additionalFunctionX(self):
        pass

class Driver:
   def coreFunctionA(self):
      pass
   def coreFunctionB(self):
      pass
   def asYDriver() -> YDriver:
      return None


class DriverModelC(Driver):
   def asYDriver() -> YDriver:
      return ModelC_YDriver(self)

然后你用 asYDriver().

检查你的 Driver 对象的特征 Y

如果系统需要更多不同的功能,您可以使其更灵活(因此更不安全)并添加 Driver.asFeatureByName(name: str)