我想覆盖继承类中的一些默认类属性,这些属性会影响中间类的功能。例如,在下面的代码片段中,在中间Child
的初始化中,我希望对internal_setting
的调用依赖于GrandChild
设置的_a
,以便输出都是that
。
class Parent():
def __init__(self):
# set a basic parameter
self._a = True
def externally_called_method(self):
# uses correct self._a
if self._a:
self.externally_set = "this"
else:
self.externally_set = "that"
class Child(Parent):
def __init__(self):
super().__init__()
self.internal_settings()
def internal_settings(self):
# uses most recent self._a
if self._a:
self.internally_set = "this"
else:
self.internally_set = "that"
class GrandChild(Child):
def __init__(self):
super().__init__()
self._a = False
g = GrandChild()
g.externally_called_method()
print("Internally set: {}".format(g.internally_set))
print("Externally set: {}".format(g.externally_set))
>>> Internally set: this
>>> Externally set: that
中间(Child
)类的__init__
调用的方法是否可能使用GrandChild
类的属性?
我知道我可以让_a
成为一个参数,但我不喜欢这样做,因为在实际的程序中,Parent
类有大量的属性,可以被子类覆盖。第二个问题是,一般来说,这是否是一种糟糕的方法,即通过继承类的阶梯来促进自定义,其中属性可以根据用例设置。
一旦你运行一个方法,它将运行体贴-如果Parent.__init__
被调用初始化参数,它是从Child.__init__
调用的,没有办法你可以从GrandChild.__init__
改变:它可以,显然,只是运行Child.__init__
作为一个单一的调用。
然而,如果你把你的类分解成更多的组件,这是很容易修复的。
如果参数可以是类属性,就像在__init__
之外声明它们一样简单,oo的自然继承规则将为您工作:
class Parent():
_a = True
def __init__(self):
# basic parameters are set as class attributes.
...
...
class GrandChild(Child):
_a = False
def __init__(self):
super().__init__()
如果它们不能是直接的类属性(由于需要从运行时输入传递给__init__
),您所要做的就是将类的职责分解为更多的方法(可以调用这些方法"槽"),因此,__init__
而不是初始化所有参数的责任,然后调用internal_settings
-可以将初始化参数的责任委托给另一个方法。这样,你就可以在孙子上重写那个方法:
class Parent():
def __init__(self):
self._set_parameters()
def _set_parameters(self):
self._a = True
def externally_called_method(self):
# uses correct self._a
if self._a:
self.externally_set = "this"
else:
self.externally_set = "that"
class Child(Parent):
def __init__(self):
super().__init__()
self.internal_settings()
...
class GrandChild(Child):
def __init__(self):
super().__init__()
def _set_parameters(self):
self._a = False
当然,你的问题比这更复杂——但你所要做的就是把所有的初始化或任务移动到单独的方法中,这样你就可以根据需要替换子类中的任何设置。