我有一个父类,它保存某种类型的列表,并具有将对象添加到这些列表的函数。它是一个抽象类,我永远不会实例化它,而只是用作其他子类的蓝图。 (也许继承ABC
然后?)
但我希望父类的某些函数不能直接在子类上调用。我尝试这样做并引发异常,但随后我需要为所有子类执行此样板,这是我不想要的。我还尝试了一个装饰器,它引发了异常,但是当我在子类中 super().__init__()
时,我无法执行初始列表添加,因为这不会执行父类.
class Parent():
def __init__(self, name:str = None, some_list=[]):
self.name = name
self.important_list = []
for i in some_list:
self.add_to_list(i)
def add_to_list(self, x):
... # important list manipulation etc
@predefined
class Child(Parent):
def __init__(self, name:str = None, some_list=[]):
super().__init__(name, some_list)
def add_to_list(self, x):
raise NotImplementedError # this function call shall be prohibited on the child!
def predefined(cls):
@functools.wraps(cls, updated=())
class Predefined(cls):
def add_to_list(self, x): raise NotImplementedError
return Predefined
我应该使用什么样的设计?谢谢!
最佳答案
如果必须,您可以通过调用 Parent.add_to_list
作为父类中的未绑定(bind)方法来实现此类行为。
所以不要调用:
self.add_to_list(i)
调用:
Parent.add_to_list(self, i)
这样,即使子实例的 add_to_list
方法被重写,也可以通过显式调用父类的 add_to_list
方法来完成子实例的初始化。
自 Python 3.6 起,您还可以覆盖 __init_subclass__
中所有子类的 add_to_list
方法。父类的类方法,这样您就不必为每个子类应用装饰器:
class Parent:
def __init__(self, some_list):
self.important_list = []
for i in some_list:
Parent.add_to_list(self, i)
def add_to_list(self, x):
self.important_list.append(x)
def __init_subclass__(cls):
def add_to_list(self, x):
raise NotImplementedError
cls.add_to_list = add_to_list
class Child(Parent):
pass
这样:
c = Child([1, 2])
print(c.important_list)
c.add_to_list(3)
输出:
[1, 2]
并引发NotImplementedError
。
关于Python继承和重载问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77139984/