首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确组织一组课程?

如何正确组织一组课程?
EN

Stack Overflow用户
提问于 2015-05-21 14:19:53
回答 2查看 223关注 0票数 0

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

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

代码语言:javascript
复制
class BaseObject:
    class Actuator:
        pass
    class Sensor:
        pass

我希望确保从BaseObject继承的所有对象都必须有一个类Actuator和一个类Sensor

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

代码语言:javascript
复制
class Camera(BaseObject):
    class Actuator:
        pass
    class Sensor:
        def get_frame():
            pass
        def set_parameter():
            pass

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

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

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

  • 您可以从元类Camera创建元类( BaseObject )。
  • 您可以强制在元类中实现类(如Actuator中的BaseObject)和如何实现(通过@abc.abstractmethod ?)
  • 您可以强制在元类中的类中实现方法吗?(如get_frame())
  • 这真的是唯一的办法吗,还是我应该以完全不同的方式组织我的课程?
  • 我该回去做纸飞机了吗?(请不要回答这个问题)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-21 18:43:18

我希望强制这些类/函数的实现对每个新对象保持相同的语法,这样如果我想使用另一个摄像机,我可以保留以前的脚本,只需要创建一个新的camera对象。

你真的是指"object“(=>实例)还是子类?但不管怎样:

既然您提到“传感器”和“执行器”对于不同的BaseObject子类不一定具有相同的接口,那么现在让我们忽略整个BaseObject部分,而专注于Camera部分。

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

在这一点上,我们(至少我)没有足够的上下文来决定我们是否需要抽象的BaseCamera类型,或者我们是否只需要抽象的BaseCameraSensorBaseCameraActuator接口。可以肯定的是,我们确实需要BaseCameraSensorBaseCameraActuator,所以让我们从这里开始。我假设传感器和执行器也需要知道它们所属的相机,FWIW确实是在尖叫“策略”模式,所以我们从一个基类开始--让我们称之为"BaseStrategy“--除了获得对其主机对象的引用之外,没有什么作用:

代码语言:javascript
复制
class Strategy(object):
    def __init__(self, parent):
        self._parent = parent

现在,让我们定义"CameraSensor“和"CameraActuator”接口:

代码语言:javascript
复制
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

现在我们可以处理“摄像机”部分了。如果实现的唯一变体部分封装在SensorActuator中(这是策略模式的要点),那么我们不需要抽象基类-我们只需将适当的SensorActuator子类作为params传递给初始化器:

代码语言:javascript
复制
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)

问题就解决了。FWIW,请注意,您并不真正需要Strategy类或ABC部件,只需要记录sensor_classactuator_class的预期界面,如果它们不受尊重就让程序崩溃就足够了--这就是我们多年来用Python编程的方式(就我而言,15+年)和it JustWork(tm) --但ABC至少使合同更加清晰,程序会更快崩溃。但是,不要被愚弄:它不会使您的代码被愚弄(提示:没有什么,就这样)。

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

票数 2
EN

Stack Overflow用户

发布于 2015-05-21 14:30:34

我会这样实施:

代码语言:javascript
复制
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'

每个子类都有一个执行器和一个传感器param。如果在子类中覆盖super.__init__,请确保调用__init__

代码语言:javascript
复制
Class Sensor:
    __metaclass__ = ABCMeta
    pass

class CameraSensor(Sensor):
    __metaclass__ = ABCMeta
    @abstractmethod
    def get_frame():
        pass
    @abstractmethod
    def set_parameter():
        pass

class Camera(BaseObject):
    def _get_sensor(self):
        # get the sensor
        assert issubclass(sensor, CameraSensor)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30376505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档