如何在 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)
。
我必须为不同的硬件驱动程序概念化一个软件模型。所讨论的硬件是具有相同核心功能但不同附加功能的测量仪器。驱动程序以及使用驱动程序的脚本在 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)
。