【发布时间】:2022-12-10 16:26:43
【问题描述】:
我正在编写一个 Python 类 A,方法 square() 返回该类的一个新实例,其第一个属性为平方。例如:
class A:
def __init__(self, x):
self.x = x
def square(self):
return self.__class__(self.x**2)
我想在子类 B 中使用此方法,以便它返回 B 的实例,其中 x 是平方的,但 B 的所有附加属性不变(即从实例中获取)。我可以通过像这样覆盖square()来让它工作:
class B(A):
def __init__(self, x, y):
super(B, self).__init__(x)
self.y = y
def square(self):
return self.__class__(self.x**2, self.y)
如果我不覆盖 square() 方法,这个小代码示例将失败,因为我需要在 B 的构造函数中为 y 传递一个值:
#test.py
class A:
def __init__(self, x):
self.x = x
def square(self):
return self.__class__(self.x**2)
class B(A):
def __init__(self, x, y):
super(B, self).__init__(x)
self.y = y
#def square(self):
# return self.__class__(self.x**2, self.y)
a = A(3)
a2 = a.square()
print(a2.x)
b = B(4, 5)
b2 = b.square()
print(b2.x, b2.y)
$ python test.py
9
Traceback (most recent call last):
File "test.py", line 20, in <module>
b2 = b.square()
File "test.py", line 6, in square
return self.__class__(self.x**2)
TypeError: __init__() takes exactly 3 arguments (2 given)
覆盖该方法一次不是问题。但是 A 可能有多个类似于 square() 的方法,并且可能有更多的子(子)类。如果可能的话,我想避免覆盖所有这些子类中的所有这些方法。
所以我的问题是:
我能否以某种方式在A 中实现方法square(),以便它返回当前子类的新实例,其中包含x 平方以及从self 获取的构造函数所需的所有其他属性(保持不变)?还是我必须继续为每个子类覆盖square()?
提前致谢!
【问题讨论】:
-
简而言之:如果您需要构造一个新实例,那么您需要向该新实例传递它需要实例化的所有参数,如果您实例化的那个类有所不同,那么是的,每个子类都必须重写根据需要自定义它的方法。没有真正的捷径,除非您的类非常可预测并遵循某些模式,因此可以自动读取现有属性并将它们作为 kwargs 传递给构造函数。
标签: python inheritance overwrite