继承最佳实践:* args,** kwargs或显式指定参数 [英] Inheritance best practice : *args, **kwargs or explicitly specifying parameters

查看:135
本文介绍了继承最佳实践:* args,** kwargs或显式指定参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常发现自己覆盖了父类的方法,并且永远无法决定是否应该明确列出给定的参数,或者只是使用毯子 * args,** kwargs 构造。一个版本比另一个好吗?有最好的做法吗?我缺少什么(dis-)优势?

I often find myself overwriting methods of a parent class, and can never decide if I should explicitly list given parameters or just use a blanket *args, **kwargs construct. Is one version better than the other? Is there a best practice? What (dis-)advantages am I missing?

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

显式变体的感知好处


  • 更明确(禅的禅)

  • 更容易掌握

  • 轻松访问的功能参数

一揽子变体的感知好处


  • 更多DRY

  • 父类可以轻松互换

  • 传播父方法中默认值的更改而不触及其他代码

推荐答案

Liskov替换原则

一般情况下,您不希望方法签名到派生类型各不相同。如果要交换派生类型的使用,这可能会导致问题。这通常被称为 Liskov替代原则

Generally you don't want you method signature to vary in derived types. This can cause problems if you want to swap the use of derived types. This is often referred to as the Liskov Substitution Principle.

明确签名的好处

与此同时,我认为所有方法都不具备<$ c $的签名是正确的c> * args , ** kwargs 。显式签名:

At the same time I don't think it's correct for all your methods to have a signature of *args, **kwargs. Explicit signatures:


  • 帮助通过良好的参数名称记录方法

  • 帮助记录方法通过指定哪些args是必需的以及哪些具有默认值

  • 提供隐式验证(缺少必需的args抛出明显的异常)

可变长度参数和耦合

不要将可变长度参数误认为是良好的耦合实践。父类和派生类之间应该有一定的内聚力,否则它们就不会彼此相关。相关代码导致耦合反映内聚水平是正常的。

Do not mistake variable length arguments for good coupling practice. There should be a certain amount of cohesion between a parent class and derived classes otherwise they wouldn't be related to each other. It is normal for related code to result in coupling that reflects the level of cohesion.

使用可变长度参数的位置

使用可变长度参数不应该'是你的第一选择。当你有充足的理由时应该使用它:

Use of variable length arguments shouldn't be your first option. It should be used when you have a good reason like:


  • 定义一个函数包装器(即装饰器)。

  • 定义参数化多态函数。

  • 当您可以采用的参数确实是完全可变的时(例如,通用的DB连接函数)。数据库连接函数通常采用多种不同形式的连接字符串,包括单个arg形式和多arg形式。不同数据库也有不同的选项集。

  • ...

  • Defining a function wrapper (i.e. a decorator).
  • Defining a parametric polymorphic function.
  • When the arguments you can take really are completely variable (e.g. a generalized DB connection function). DB connection functions usually take a connection string in many different forms, both in single arg form, and in multi-arg form. There are also different sets of options for different databases.
  • ...

你做错了吗?

如果你发现你经常创建带有许多参数的方法或带有不同签名的派生方法,你可能会遇到更大的问题在如何组织代码中。

If you find you are often creating methods which take many arguments or derived methods with different signatures you may have a bigger issue in how you're organizing your code.

这篇关于继承最佳实践:* args,** kwargs或显式指定参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆