覆盖时调用super().__ init __()会给出错误的方法

时间:2019-07-15 15:15:53

标签: python inheritance super

我有一个基类和一个子类。在基类中,我有一个实例方法,该方法在type中被调用。在子类中,我重写了此方法。子类中的__init__调用不调用原始基方法,而是调用重写的子类方法。为什么?

super()

我希望打印输出为“基本”,但实际输出为“ sub”。如何在不显式调用class BaseClass: def __init__(self, value): self.value = value self.transformed_value = self.create_value(value) def create_value(self, value): print("base") return value + 1 class SubClass(BaseClass): def __init__(self, value): super().__init__(value) def create_value(self, value): print("sub") return value + 2 s = SubClass(3) 的{​​{1}}中调用BaseClass.create_value(self, value)的情况下修改代码以获取“基础”?

2 个答案:

答案 0 :(得分:2)

Python是动态类型的。那意味着当你写

def __init__(self, value):
    self.value = value
    self.transformed_value = self.create_value(value)

在评估self.create_value时该方法所属的类无关紧要:仅在调用该方法时self type 是重要的。

当您调用SubClass(3)时,您最终将调用SubClass.__init__,后者立即使用类型为BaseClass.__init__的参数调用SubClass。由于SubClass.create_value已定义,因此self.create_value会解决。

如果出于任何原因坚持使用BaseClass.__init__调用BaseClass.create_value,则必须使用self。但是,这很少是一个好主意。如果BaseClass.create_value(self, value)的类型想要调用它重写的方法,则使用self本身是这样做的 责任:

super

答案 1 :(得分:1)

进一步添加到@chepner的优雅答案中,如果您希望父类调用它自己的方法,则可以如下修改父类:

figure {
  position: relative;
  width: 30%;
  margin: 50px 0 50px 35%;
  overflow:hidden;
}

figure > a img {
  display: block;
  width: 100%;
  margin-bottom: 50%;
}

figcaption {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 33%;
  background:#ad7;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

figcaption > span {
  font: 600 12px Roboto, sans-serif;
}

在上面的<figure> <a href="Reading/Issues/who.pdf"> <img src="https://picsum.photos/187/240"> </a> <figcaption> <h2>Issue#</h2> <span>Name</span> </figcaption> </figure>中,我们正在创建对父方法的简单引用,并在其自己的class BaseClass: def __init__(self, value): self.value = value self.transformed_value = self.base_create_value(value) # use the renamed reference def create_value(self, value): print("base") return value + 1 base_create_value = create_value # create a local reference to the method 方法中使用相同的引用。这样,即使基类的方法被覆盖并且由子实例调用时,我们也可以继续使用此引用对象。