【问题标题】:What is the practical use of the keyword super in Python inheritance? [closed]Python继承中关键字super的实际用途是什么? [关闭]
【发布时间】:2015-06-07 05:14:06
【问题描述】:

我有点理解,ChildClass 中继承自 BaseClass 的关键字 super 是为了防止在 ChildClass 具有相同方法时覆盖基类的方法。这有什么实际用途?

例如:

class BaseClass():
    def save(*args, **kwargs):
        print "save from BaseClass"

class ChildClass(BaseClass):
    def save(self, *args, **kwargs):
        super(ChildClass, self).save(*args, **kwargs)
        print "save from ChildClass"


someObject = ChildClass()
someObject.save()
​

输出:

save from BaseClass
save from ChildClass

【问题讨论】:

  • super() 不调用任何东西;您仍然必须显式调用父方法。它使您可以访问父类上的方法的实现,因此您可以根据需要重用该实现。
  • 我不完全清楚你的问题是什么。如果ChildClass.save() 必须进行一些额外的处理,但您不想复制所有工作 BaseClass.save() 会怎样?这就是 super() 的用武之地,您可以重用原始的 save() 方法,而无需再次执行所有这些工作,但您可以添加到原始行为的同时向 ChildClass 的用户提供一致的 API。
  • 认为您要问的是调用父方法的用途,但您可能完全是在问其他问题。
  • 想象BaseClass.save() 可以存储一些文档,但不会通知用户有关保存状态的信息。因此,您可以extend BaseClass 并调用super.save(...)(保存文档)然后通知用户保存状态...为什么要使用super 前缀调用?由于您的子方法完全按照父 (.save(...)) 调用,您需要告诉编译器调用父保存。如果你不这样做,它会无限调用自己并抛出错误......

标签: python django


【解决方案1】:

我有点理解...

你已经尝试了两次,都不正确:

  • “将同时调用父类方法和子类方法” - 不,它在 MRO(方法解析顺序)中调用下一个类的方法;和
  • “是为了防止在ChildClass 具有相同方法时覆盖基类的方法” - 不,子类实现确实 覆盖了基类,@ 987654322@ 允许您在不显式指定类的情况下访问继承的实现。

这个有什么实际用途?

在最简单的情况下,假设我们有一个带有一个初始化参数的基类:

def Base(object):

    def __init__(self, attr1):
        self.attr1 = attr1

还有一个有两个的子类。然后我们可以通过以下两种方式之一实现子类,或者不调用基类:

def Child(Base):

    def __init__(self, attr1, attr2):
        self.attr1 = attr1 
        self.attr2 = attr2

或通过调用基类:

def Child(Base):

    def __init__(self, attr1, attr2):
        super(Child, self).__init__(attr1)
        self.attr2 = attr2

请注意,这减少了重复,如果我们在 Base 类中更改 attr1 的处理(例如,我们将参数分配给“私有”属性 _attr1 并通过 @property 访问它)我们只需进行一次更改


您也可以将第二个实现为:

def __init__(self, attr1, attr2):
    Base.__init__(self, attr1)
    self.attr2 = attr2

但这又意味着重复 - 我们现在必须在 Child 的两个地方指定名称 Base,所以如果我们重命名 Base 或更改 Child 的继承,我们必须进行更改在两个地方。

【讨论】:

  • 好的,感谢您的纠正和解释。在那种情况下,我根本不完全理解它。这就是为什么我的问题以我“有点”开头的原因
猜你喜欢
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2010-11-13
  • 2018-05-30
  • 2012-06-18
  • 1970-01-01
相关资源
最近更新 更多