加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 强制子类在重写时调用父方法

发布时间:2020-12-16 23:03:46 所属栏目:Python 来源:网络整理
导读:我很好奇,Python是否有一种方法强制(从Parent类)为父类方法从子类被重写时被调用. 例: class Parent(object): def __init__(self): self.someValue=1 def start(self): ''' Force method to be called''' self.someValue+=1 正确执行我想要我的孩子孩子班做
我很好奇,Python是否有一种方法强制(从Parent类)为父类方法从子类被重写时被调用.

例:

class Parent(object):

    def __init__(self):
        self.someValue=1

    def start(self):
        ''' Force method to be called'''
        self.someValue+=1

正确执行我想要我的孩子孩子班做的是:

class ChildCorrect(Parent):

    def start(self):
        Parent.start(self)
        self.someValue+=1

但是,有没有办法强制开发者开发Child类来专门调用(不只是覆盖)Parent类中定义的’start’方法,以防他们忘记调用它:

class ChildIncorrect(Parent):

    def start(self):
        '''Parent method not called,but correctly overridden'''
        self.someValue+=1

另外,如果这不是最佳做法,那又有什么办法呢?

解决方法

如何(不)做到这一点

不,没有安全的方法来强迫用户打电话给超级用户.让我们来看几个可以达到或类似目标的选项,并讨论为什么这是一个坏主意.在下一节中,我还将讨论什么是明智的(相对于Python社区)来处理这种情况的方式.

>元类可以在子类定义时检查覆盖目标方法的方法(=是否与目标方法具有相同的名称)使用适当的参数调用super.

这需要深入的实现特定行为,例如使用CPython的dis模块.在任何情况下,我都无法想象这是一个好主意 – 它取决于CPython的具体版本以及您正在使用CPython的事实.
元类可以与基础类合作.在这种情况下,baseclass在继承的方法被调用时通知元类,并且metaclass使用一段保护代码封装任何重写方法.

守护代码测试在重写方法的执行过程中是否调用了继承的方法.这是有缺点的,需要针对需要这个“特征”的每个方法的单独的通知通道,并且线程安全性将是一个问题.此外,重写方法已经完成执行,您注意到它没有调用继承的方法,这可能会因为您的方案而不好.

它还打开了一个问题:如果重写方法没有称为继承方法,该怎么办?使用该方法的代码可能会引发异常(或者更糟的是,它可能认为该方法根本没有效果,这不是真的).

而且,迟来的反馈,开发人员超越了这个课程(如果他们得到所有的反馈!)是不好的.
>元类可以为每个覆盖方法生成一个保护代码,该方法在执行重写方法之前或之后自动调用继承的方法.

这里的缺点是开发人员不会期望继承的方法被自动调用,并且无法阻止该调用(例如,如果不满足子类的特殊条件),或者在其自己的覆盖方法中控制继承的方法是调用.

在编码python时,这违反了一大堆明智的原则(避免意外,明确比隐含更好,更可能更多).
>点3和4的组合.使用第3点的基类和元类的合作,来自第4点的保护码可以扩展为自动调用超级,如果覆盖方法没有称为超级本身.

再次,这是意想不到的,但它解决了重复超级调用的问题,以及如何处理不调用超级的方法.

但是,仍然存在问题.虽然线程安全性可以用线程本地化来修复,但是除非通过引发在所有情况下都不需要的异常,否则重写方法在没有满足前提条件的情况下中止超级调用超级.此外,超级只能在重写方法之后自动调用,而不是之前,在某些情况下,再次也是不希望的.

此外,这不是有助于在对象和类的生命周期内重新绑定属性,虽然可以通过使用描述符和/或扩展元类来处理该属性来帮助它.

为什么不这样做

Also,if this is not considered best practice,what would be an alternative?

使用Python的常见的最佳做法是假设您同意成年人.这意味着,除非你允许他们,否则没有人正在积极地尝试对你的代码做恶劣的事情.在这样一个生态系统中,在方法或类的文档中处理一个警告::这是有意义的,所以从该类继承的任何人都知道他们要做什么.

此外,在适当的时候调用超级方法在许多上下文中都是有意义的,开发人员使用基类将会考虑它,只会不小心忘记它.在这种情况下,使用上述第三点的元类不会帮助用户不必记住不要调用超级,这本身可能是一个问题,特别是对于有经验的程序员.

它也违反了最不奇怪的原则,“明确比隐含更好”(没有人期望继承的方法被隐含地调用!).这样一来,必须记录得很好,在这种情况下,您也可以诉诸于没有超级被自动调用,并且仅仅记录它比通常调用继承方法更有意义.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读