调用super()。\uuu init\uuu()在重写时给出错误的方法

2024-03-29 11:57:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个基类和一个子类。在基类中,我有一个实例方法,在__init__中调用。在子类中,我重写了这个方法。子类中的super()调用不调用原始的基方法,而是调用重写的子类方法。为什么?你知道吗

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)

我希望打印输出是“base”,但实际输出是“sub”。如何修改代码以获得“base”,而不显式调用BaseClass__init__中的BaseClass.create_value(self, value)?你知道吗


Tags: 方法selfbasereturninitvaluedefcreate
2条回答

为了进一步补充@chepner的优雅回答,如果您希望父类调用自己的方法,您可以如下修改父类:

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

在上面的BaseClass中,我们正在创建一个对父方法的简单引用,并在它自己的__init__方法中使用相同的引用。通过这样做,即使基类的方法被重写并且被子实例调用,我们也可以继续使用这个引用对象。你知道吗

Python是动态类型的。也就是说当你写作的时候

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

在计算self.create_value时,is与该方法属于哪个类无关:它只与调用该方法时self类型有关。你知道吗

当您调用SubClass(3)时,最终会调用SubClass.__init__,它会立即使用SubClass类型的参数调用BaseClass.__init__。既然SubClass.create_value是定义的,那就是self.create_value的解析。你知道吗

如果出于任何原因,您坚持BaseClass.__init__在其self参数上调用BaseClass.create_value,则必须显式地使用BaseClass.create_value(self, value)。然而,这很少是个好主意。如果self的类型希望调用它重写的方法,那么通过使用super本身,这就是它的责任:

def create_value(self, value):
    rv = super().create_value()
    print("sub")
    return value + 2  # Or perhaps do something with rv first?

相关问题 更多 >