继承:更改子方法的签名

2024-04-16 18:50:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找出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

{{{bit}的另一个方法的实现只需要一个cd3}方法

^{pr2}$

所以问题是如何以一种更“python”的方式来实现这一点,同时考虑到python的最佳实践?当然,我们可以在父(子)方法中使用*args, **kwargs和其他类似**kwargs的方法,但我担心这会降低代码的可读性(自我记录)。在


Tags: 对象方法selfnoneobjectinitdefcreate
2条回答

我不确定是否有Python式的方法来做这件事,因为你可以像你在问题中那样做。更确切地说,这更多的是关于OOP的,而不是关于python的问题。在

所以我假设在BaseClient中实现了其他方法,而不是其他子级共享的create(否则,没有必要使ClientC成为{}的子级)。在您的例子中,看起来ClientC由于需要create方法的不同签名而与其他方法不同。那么也许是时候考虑把它们分开了?在

例如,您可以让根BaseClient实现除create之外的所有共享方法,然后再拥有两个“base”子级,如下所示:

class EntityBasedClient(BaseClient):
    def create(self, entity_id, data=None):
        pass

class DataBasedClient(BaseClient):
    def create(self, data):
        pass

所以现在您可以继承而不违反任何规则:

^{pr2}$

另外,如果这两个版本的create实现非常相似,那么可以通过在带有签名_create(self, entity_id=None, data=None)的{}中实现一个更通用的私有方法,然后从EntityBasedClientDataBasedClient内部使用适当的参数调用它,从而避免代码重复。在

我会说,只需将参数作为关键字添加回默认值None。然后引发一个错误,解释某些输入数据丢失。在

 class ClientC(BaseClient):
 ....
     def create(self,entity_id=None, data):
         if entity_id:
             raise RedudantInformationError("Value for entity_id does nothing")
         pass

这样,每当程序员试图像处理其他childs一样处理childc时,他会得到一个警告提醒他,但是他可以通过使用try语法轻松地一步一步地完成。在

相关问题 更多 >