[英]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_frame
和set_parameters
。
我想強制實現這些類/函數,以便為每個新對象保留相同的合成器,因此,如果要與其他攝像機一起使用,可以保留以前的腳本,只需要創建一個新的Camera
對象即可。 您還應該知道,這些類不會被直接實例化,而是可以建立的。
我看了元類,看上去很不錯,可以強制在類中實現方法,但是我不確定是否:
BaseObject
創建元類( Camera
) Actuator
在BaseObject
(通過),以及如何@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
類型。 該類型必須具有sensor
和actuator
屬性,它們都必須遵守給定的接口,但可能具有不同的實現方式。
至此,我們(至少,至少是我)沒有足夠的上下文來決定我們是否需要抽象BaseCamera
類型,還是僅需要抽象BaseCameraSensor
和BaseCameraActuator
接口。 可以確定的是,我們確實需要BaseCameraSensor
和BaseCameraActuator
所以讓我們開始吧。 我認為傳感器和執行器也需要知道它們所屬的攝像機,這是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
現在,我們可以處理“相機”部分。 如果實現的唯一變體部分封裝在Sensor
和Actuator
(這是策略模式的重點),則我們不需要抽象基類-我們可以將適當的Sensor
和Actuator
子類作為參數傳遞給初始化程序:
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_class
和actuator_class
,讓程序崩潰,如果他們不尊重就夠了-這就是如何我們在Python編程了對年(就我而言,已超過15年)和JustWork(tm)-但ABC至少使合同更加明確,程序會更快崩潰。 但是請不要上當:它不會使您的代碼萬無一失(提示:不會,期間)。
現在,如果我們還有其他變體部分,無法提前知道實現,則最簡單的解決方案將是遵循相同的模式-委托給實例化時傳遞的Strategy對象。 因此,重點是:現在我們已經實現了這一點,我們發現我們不需要某些BaseCamera
ABC。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.