簡體   English   中英

如何正確安排一組課程?

[英]How to organize a set of classes properly?

我想通過繼承創建一組對象,並且需要一些建議來組織實現。

所有對象都必須繼承自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

我想強制實現這些類/函數,以便為每個新對象保留相同的合成器,因此,如果要與其他攝像機一起使用,可以保留以前的腳本,只需要創建一個新的Camera對象即可。 您還應該知道,這些類不會被直接實例化,而是可以建立的。

我看了元類,看上去很不錯,可以強制在類中實現方法,但是我不確定是否:

  • 您可以從元類BaseObject創建元類( Camera
  • 您可以強制執行一類的元類(如ActuatorBaseObject (通過),以及如何@abc.abstractmethod ?)
  • 您可以在元類內部的類中強制執行方法? (如get_frame()
  • 真的是唯一的方法還是我應該完全不同地組織我的課程?
  • 我是否應該再去制作紙飛機? (請不要回答這個)

我會這樣實現它們:

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'

每個子類都有一個執行器和一個傳感器參數。 如果您在子類中重寫__init__ ,請確保調用super.__init__ __init__

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)

我想強制實現這些類/函數,以使每個新對象都保持相同的語法,因此,如果要使用其他攝像機,可以保留以前的腳本,只需要創建一個新的Camera對象即可。

OT:您真的是說“對象”(=>實例)還是子類? 但無論如何:

由於您提到“傳感器”和“執行器”不一定要針對不同的BaseObject子類具有相同的接口,因此我們BaseObject忽略整個BaseObject部分,而專注於Camera部分。

如果我理解正確,那么您想要的是通用Camera類型。 該類型必須具有sensoractuator屬性,它們都必須遵守給定的接口,但可能具有不同的實現方式。

至此,我們(至少,至少是我)沒有足夠的上下文來決定我們是否需要抽象BaseCamera類型,還是僅需要抽象BaseCameraSensorBaseCameraActuator接口。 可以確定的是,我們確實需要BaseCameraSensorBaseCameraActuator所以讓我們開始吧。 我認為傳感器和執行器也需要知道它們所屬的攝像機,這是FWIW真正尖叫的“戰略”模式,因此我們從一個基類開始-我們稱之為“ BaseStrategy”-除了獲得一個對其宿主對象的引用:

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

現在,讓我們定義“ CameraSensor”和“ CameraActuator”接口:

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子類作為參數傳遞給初始化程序:

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年)和JustWork(tm)-但ABC至少使合同更加明確,程序會更快崩潰。 但是請不要上當:它不會使您的代碼萬無一失(提示:不會,期間)。

現在,如果我們還有其他變體部分,無法提前知道實現,則最簡單的解決方案將是遵循相同的模式-委托給實例化時傳遞的Strategy對象。 因此,重點是:現在我們已經實現了這一點,我們發現我們不需要某些BaseCamera ABC。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM