【发布时间】:2018-01-13 08:35:03
【问题描述】:
当有一个“坏主意”改变孩子的方法签名时,我试图弄清楚 Python 继承原则中的最佳实践是什么。
假设我们有一些基类 BaseClient 已经实现了 create 方法(和一些抽象方法),它适用于几乎所有的“后代”,除了一个:
class BaseClient(object):
def __init__(self, connection=None):
pass
def create(self, entity_id, data=None):
pass
class ClientA(BaseClient):
pass
class ClientB(BaseClient):
pass
唯一的类 ClientC 需要另一个实现 create 方法并带有一点其他方法签名
class ClientC(BaseClient):
....
def create(self, data):
pass
所以问题是如何以更“pythonic”的方式制作它,同时考虑到最佳 python 实践?当然我们可以在父(子)方法中使用*args, **kwargs 和其他类似**kwargs 的方法,但我担心它会降低我的代码的可读性(自我记录)。
【问题讨论】:
-
替换原则:子类不能做基类可以做的事情通常不是好的设计 -
x.create(entity_id)适用于BaseClient所以它应该适用于它的子类。 -
为什么ClientC需要另一个create实现?
-
zch 所说:子类型可以向方法签名中添加新参数,但不应删除它们,因为这违反了Liskov substitution principle。
-
IMO 最好向
ClientC添加一个接受所需参数并返回其实例的类方法。这是可以接受的,因为该类的用户在创建实例时已经知道他们想要该子类(因此大概也只知道它具有的类方法)。 -
如果没有任何其他上下文,我认为
BaseClient应该有两种方法:create_with_entity,它与您当前的create具有相同的签名,以及一个新的create,它没有取一个entity_id,可能只是create_with_entity的包装。
标签: python oop inheritance overriding