如何正确组织一组课程?

时间:2015-05-21 14:19:53

标签: python python-2.7 oop

我想通过继承创建一组对象,我需要一些建议来组织我的实现。

所有对象都必须从BaseObject继承,如下所示:

class BaseObject:
    class Actuator:
        pass
    class Sensor:
        pass

我想确保从BaseObject继承的所有对象都被强制拥有类Actuator和类Sensor

然后我有另一个抽象级别,带有一些泛型对象,例如:

class Camera(BaseObject):
    class Actuator:
        pass
    class Sensor:
        def get_frame():
            pass
        def set_parameter():
            pass

我希望我创建的每个Camera对象至少有get_frameset_parameters

我想强制实现这些类/函数,以便为每个新对象保留相同的synthax,这样如果我想使用其他相机,我可以保留以前的脚本,我只需要创建一个新的{{ 1}}对象。 您还应该知道这些类不会直接实例化,而是构建的模式。

我查看了元类,在类中强制实现方法看起来不错,但我不确定是否:

  • 您可以从元类Camera
  • 创建元类(Camera
  • 您可以强制在元类中实现类(如BaseObject中的Actuator)以及如何(通过BaseObject?)
  • 你可以强制在一个类内部的类中实现方法吗? (如@abc.abstractmethod
  • 这真的是唯一的方式,还是我应该以不同的方式组织我的课程?
  • 我应该更好地回到制作纸飞机吗? (请不要回答这个问题)

2 个答案:

答案 0 :(得分:3)

我会这样实现它们:

printf("%s", buf);

每个子类都有一个执行器和一个传感器参数。如果您在子类中覆盖from abc import ABCMeta class BaseObject: __metaclass__ = ABCMeta def __init__(self): self.actuator = self._get_actuator() self.sensor = self._get_sensor() @abstractmethod def _get_actuator(self): return 'actuator' @abstractmethod def _get_sensor(self): return 'sensor' ,请务必致电super.__init__

__init__

答案 1 :(得分:2)

  

我想强制执行这些类/函数来保持   每个新对象的语法相同,所以如果我想使用它   另一个相机,我可以保留我以前的脚本,我只需要创建   一个新的Camera对象。

OT:你真的是说"对象" (=>实例),或子类?但无论如何:

既然你提到过"传感器"和"执行器"对于不同的BaseObject子类,不一定应该具有相同的接口,暂时忽略整个BaseObject部分并集中在Camera部分。

如果我理解正确,您想要的是通用Camera类型。此类型必须具有sensoractuator属性,这两个属性都必须遵循给定的接口,但可能具有不同的实现。

此时我们(好吧,我至少)没有足够的上下文来决定我们是否需要抽象BaseCamera类型,或者我们是否需要抽象BaseCameraSensor和{{1接口。可以肯定的是,我们确实需要BaseCameraActuatorBaseCameraSensor,所以让我们从此开始。我认为传感器和执行器需要知道它们所属的相机,哪个FWIW真的尖叫"策略"模式,所以我们从一个基类开始 - 让我们称之为" BaseStrategy" - 除了获得对它的主机对象的引用之外,它不会做太多事情:

BaseCameraActuator

现在让我们来定义我们的相机传感器"和#34; CameraActuator"接口:

class Strategy(object):
    def __init__(self, parent):
        self._parent = parent

现在我们可以照顾"相机"部分。如果实现的唯一变体部分封装在class BaseCameraSensor(Strategy): __metaclass__ = ABCMeta @abstractmethod def get_frame(self): raise NotImplementedError @abstractmethod def set_parameter(self, value): raise NotImplementedError class BaseCameraActuator(Strategy): __metaclass__ = ABCMeta @abstractmethod def random_method(self): raise NotImplementedError Sensor(这是策略模式的要点),那么我们不需要抽象基类 - 我们可以只将相应的ActuatorSensor子类作为参数传递给初始化器:

Actuator

问题解决了。 FWIW,请注意,您并不真正需要class Camera(object): def __init__(self, brand, model, sensor_class, actuator_class): self.brand = brand self.model = model assert issubclass(sensor_class, BaseCameraSensor) self.sensor = sensor_class(self) assert issubclass(actuator_class, BaseCameraActuator) self.actuator = actuator_class(self) 类或ABC部分,只需记录Strategysensor_class的预期界面,如果不是,请让程序崩溃受到尊重就足够了 - 这就是我们多年来一直用Python编程的方式(就我而言已超过15年)和JustWork(tm) - 但ABC至少让合同更加清晰程序将很快崩溃。但不要被愚弄:它不会让你的代码变得愚蠢(暗示:什么都不会,期间)。

现在,如果我们有一些其他的变体部分,实现无法提前知道,最简单的解决方案是遵循相同的模式 - 委托给在实例时传递的Strategy对象。所以重点是:现在我们实施了这个,我们发现我们不需要一些actuator_class ABC。