假设我正在编写一堆抽象类(因为我是),并且它们代表了与版本控制系统(如存储库和修订版)(因为它们)有关的事情.像SvnRevision和HgRevision和GitRevision这样的东西非常紧密地在语义上相关联,我希望他们能够做同样的事情(这样我可以在其他地方执行代码,作用于任何类型的Repository对象,并且是不可知的子类),这就是为什么我希望他们继承自抽象类.然而,它们的实现差别很大.
到目前为止,已经实现的子类共享了很多属性名称,而在很多代码之外的类本身,直接使用属性访问.例如,版本的每个子类都有一个作者属性,一个日期属性等等.但是,抽象类中的任何地方都不会描述这些属性.这似乎是一个非常脆弱的设计.
如果有人想编写修订版类的另一个实现,我觉得他们应该能够通过查看抽象类来做到这一点.然而,满足所有抽象方法的类的实现几乎肯定会失败,因为作者不会知道他们需要名为“author”和“date”的属性等等,所以试图访问Revision的代码.作者会抛出异常.可能不是很难找到问题的根源,但令人不安的是,它只是感觉像一个不巧的设计.
我的解决方案是为抽象类(get_id,get_author等)写入访问器方法.我认为这实际上是一个非常干净的解决方案,因为它消除了对属性的命名和存储的任意限制,并且清楚地显示了对象需要访问的数据.任何实现抽象类的所有方法的类都可以正常工作.
无论如何,我正在与憎恨这个解决方案的团队(似乎是因为访问者是愚蠢的,我不能真正地争论).那么可以选择什么呢?文档?还是我想象中的一个非问题?
解决方法
Note: I’ve considered properties,but I don’t think they’re a cleaner solution.
But they are.通过使用属性,您将拥有所需的类签名,同时可以将属性本身用作属性.
def _get_id(self): return self._id def _set_id(self,newid): self._id = newid
可能类似于你现在有的.要安抚你的团队,你只需要添加以下内容:
id = property(_get_id,_set_id)
您也可以使用属性作为装饰器:
@property def id(self): return self._id @id.setter def id(self,newid): self._id = newid
为了使它成为唯一的,只需省略set_id / id.setter位.