调用 super().__init__() 时会给出错误的方法
Calling super().__init__() gives the wrong method when it is overridden
我有一个基础 class 和一个子 class。在基础 class 中,我有一个在 __init__
中调用的实例方法。在 sub class 中我已经覆盖了这个方法。 sub class 中的 super()
调用不是调用原始基方法而是重写的 sub class 方法。为什么?
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)
?
Python 是动态输入的。这意味着当你写
def __init__(self, value):
self.value = value
self.transformed_value = self.create_value(value)
在评估 self.create_value
时该方法属于哪个 class 并不重要:它只重要 type of self
是调用方法的时候。
当您调用 SubClass(3)
时,您最终会调用 SubClass.__init__
,它会立即调用 BaseClass.__init__
,并使用 SubClass
类型的参数。由于 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?
进一步补充@chepner 的优雅答案,如果你想让父 class 调用它自己的方法,你可以修改父 class 如下:
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__
方法中使用了相同的方法。通过这样做,我们可以继续使用这个引用对象,即使基础 class' 方法被覆盖并且当它被子实例调用时。
我有一个基础 class 和一个子 class。在基础 class 中,我有一个在 __init__
中调用的实例方法。在 sub class 中我已经覆盖了这个方法。 sub class 中的 super()
调用不是调用原始基方法而是重写的 sub class 方法。为什么?
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)
?
Python 是动态输入的。这意味着当你写
def __init__(self, value):
self.value = value
self.transformed_value = self.create_value(value)
在评估 self.create_value
时该方法属于哪个 class 并不重要:它只重要 type of self
是调用方法的时候。
当您调用 SubClass(3)
时,您最终会调用 SubClass.__init__
,它会立即调用 BaseClass.__init__
,并使用 SubClass
类型的参数。由于 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?
进一步补充@chepner 的优雅答案,如果你想让父 class 调用它自己的方法,你可以修改父 class 如下:
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__
方法中使用了相同的方法。通过这样做,我们可以继续使用这个引用对象,即使基础 class' 方法被覆盖并且当它被子实例调用时。