我经常发现自己会覆盖父类的方法,并且永远无法决定是应该显式列出给定的参数还是仅使用通用*args, **kwargs结构。一个版本比另一个版本好吗?有最佳做法吗?我缺少什么(缺点)?
*args, **kwargs
class Parent(object): def save(self, commit=True): # ... class Explicit(Parent): def save(self, commit=True): super(Explicit, self).save(commit=commit) # more logic class Blanket(Parent): def save(self, *args, **kwargs): super(Blanket, self).save(*args, **kwargs) # more logic
显式变体的感知好处
毯子变体的感知优势
里斯科夫替代原则
通常,您不希望方法签名在派生类型中有所不同。如果要交换派生类型的使用,可能会导致问题。这通常称为Liskov替代原理。
显式签名的好处
同时,我不认为这是正确的为您的所有方法有一个签名*args,**kwargs。显式签名:
*args
**kwargs
可变长度参数和耦合
不要将变长参数误认为是良好的耦合实践。父类和派生类之间应该有一定的凝聚力,否则它们将不会相互关联。相关代码导致耦合反映内聚程度是正常的。
可变长度参数的使用位置
使用可变长度参数不应该是您的第一选择。当您有充分的理由时应使用它:
您做错什么了吗?
如果发现自己经常创建带有许多参数的方法或带有不同签名的派生方法,那么在组织代码的方式上可能会遇到更大的问题。