当前位置: 首页 > 面试题库 >

继承最佳实践:* args,** kwargs或显式指定参数

戚俊健
2023-03-14
问题内容

我经常发现自己会覆盖父类的方法,并且永远无法决定是应该显式列出给定的参数还是仅使用通用*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

显式变体的感知好处

  • 更明确(Python的禅宗)
  • 更容易掌握
  • 功能参数易于访问

毯子变体的感知优势

  • 更干
  • 父类很容易互换
  • 无需更改其他代码即可传播父方法中默认值的更改

问题答案:

里斯科夫替代原则

通常,您不希望方法签名在派生类型中有所不同。如果要交换派生类型的使用,可能会导致问题。这通常称为Liskov替代原理。

显式签名的好处

同时,我不认为这是正确的为您的所有方法有一个签名*args**kwargs。显式签名:

  • 通过良好的参数名称帮助记录方法
  • 通过指定哪些args和哪些具有默认值来帮助记录该方法
  • 提供隐式验证(缺少必需的参数会引发明显的异常)

可变长度参数和耦合

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

可变长度参数的使用位置

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

  • 定义函数包装器(即装饰器)。
  • 定义参数多态函数。
  • 当您可以接受的参数确实是完全可变的时(例如,通用的数据库连接功能)。DB连接函数通常采用多种不同形式的连接字符串,包括单arg形式和多arg形式。对于不同的数据库,还有不同的选项集。

您做错什么了吗?

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



 类似资料:
  • Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。

  • 本文向大家介绍推荐JavaScript实现继承的最佳方式,包括了推荐JavaScript实现继承的最佳方式的使用技巧和注意事项,需要的朋友参考一下    实现JavaScript继承的最简单的方式是call方法(或者apply方法)及原型链方法,但这两种方法都有缺陷,而其混合体就是很好的继承实现方式。下面举例说明:     对于类Animal来说,它有一个字段属性age及函数属性sayAge,sa

  • 这里有些给使用和编写 Ansible playbook 的贴士. 你能在我们的 ansible-example repository.找到展示这些最佳实践的 playbook 样例.(注意: 这些示例用的也许不是最新版的中所有特性,但它们仍旧是极佳的参考.) Topics 最佳实践 接下来的章节将向你展示一种组织 playbook 内容方式. 你对 Ansible 的使用应该符合你的需求而不是我们

  • 处理后台任务与常规调用方法有很大的不同。本指南旨在帮助让您的后台任务平稳有效地运行。本文基于 这篇博客文章。 使任务参数小而简单 方法(任务)在调用之前会被序列化。使用 TypeConverter 类将参数转换为 JSON 字符串。如果您有复杂的实体和 / 或大对象; 包括数组,最好将它们放入数据库,然后只将其标识 (id) 传递给后台任务。 错误例子: public void Method(En

  • VR设计 VR设计不同于平面体验设计。作为一种新的媒介,有新的最佳实践需要遵循,特别是保持用户的舒适性和存在性。这在如下指南中已经写得很透彻了: Oculus VR最佳实践 Leap Motion VR最佳实践指南 一些值得注意的事情: 公共的金科玉律是永远不要意外地把相机控制权从用户手中剥夺。 单位(比如对于位置)应该考虑使用米(m)。这是因为WebVR API以米为单位返回姿势数据,进而传送给