Coq*_*cot 9 python inheritance attributes abstract-class interface
我意识到在大多数情况下,在Python中首选只是直接访问属性,因为没有像Java等那样真正的封装概念.但是,我想知道是否没有任何异常,特别是对于具有不同实现的抽象类.
假设我正在编写一堆抽象类(因为我是),并且它们表示与版本控制系统(如存储库和修订版)有关的事情(因为它们确实如此).像SvnRevision和HgRevision以及GitRevision这样的东西在语义上非常紧密地联系在一起,我希望它们能够做同样的事情(这样我就可以将代码放在其他任何类型的Repository对象上,并且不可知子类),这就是为什么我希望它们从抽象类继承.但是,它们的实现差异很大.
到目前为止,已实现的子类共享许多属性名称,并且在类本身之外的许多代码中,使用直接属性访问.例如,Revision的每个子类都有author属性和date属性,依此类推.但是,抽象类中的任何位置都不会描述这些属性.在我看来,这似乎是一个非常脆弱的设计.
如果有人想编写Revision类的另一个实现,我觉得他们应该只通过查看抽象类就可以这样做.但是,满足所有抽象方法的类的实现几乎肯定会失败,因为作者不会知道他们需要名为"author"和"date"等属性,因此尝试访问Revision的代码.作者将抛出异常.可能不难发现问题的根源,但仍然很烦人,而且感觉就像一个不雅的设计.
我的解决方案是为抽象类(get_id,get_author等)编写访问器方法.我认为这实际上是一个非常干净的解决方案,因为它消除了对属性命名和存储方式的任意限制,并且只是明确了对象需要能够访问的数据.任何实现抽象类的所有方法的类都可以工作......感觉正确.
无论如何,我正在工作的团队讨厌这个解决方案(似乎因为访问者是untythonic的原因,我无法真正争辩).那么......有什么选择呢?文档?或者是我想象的问题是什么?
注意:我考虑了属性,但我认为它们不是一个更清洁的解决方案.
注意:我考虑了属性,但我认为它们不是一个更清洁的解决方案.
但他们是.通过使用属性,您将拥有所需的类签名,同时可以将该属性用作属性本身.
def _get_id(self):
return self._id
def _set_id(self, newid):
self._id = newid
Run Code Online (Sandbox Code Playgroud)
可能与你现在的相似.为了安抚您的团队,您只需添加以下内容:
id = property(_get_id, _set_id)
Run Code Online (Sandbox Code Playgroud)
你也可以property用作装饰者:
@property
def id(self):
return self._id
@id.setter
def id(self, newid):
self._id = newid
Run Code Online (Sandbox Code Playgroud)
为了使其成为只读,请忽略set_id/ id.setter位.