我希望继承链具有可选参数。链中的大多数类有时都需要使参数成为成员,但是我也想在其他时间使用链而不使参数成为成员。
我曾考虑过将参数设为可选类并使用import,但我想避免对成员optional
使用类语法。另外,因为沿链的所有类都在字典中用作键。
替代方案?难道我做错了什么?还有更Python化的方法吗?
class Top:
def __init__(self, optional=None):
if optional is not None:
self.optional = optional
return
class Middle(Top):
def __init__(self, one, optional=None):
if optional is not None:
super().__init__(optional)
self.one = one
class Bottom(Middle):
def __init__(self, one, two, optional=None):
if optional is not None:
super().__init__(one, optional)
else:
super().__init__(one)
self.two = two
a = Middle('one')
b = Middle('one', 'two')
c = Bottom('one', 'two')
d = Bottom('one', 'two', 'three')
答案 0 :(得分:1)
Top
已经知道如何处理optional=None
;照原样传递参数。但是,请记住,每个类都必须准备好接收并传递未知参数,以防万一您未定义的类继承自其中任何一个并将其 own 参数添加到{{1 }}。 (请考虑一个同时继承自__init__
和某个其他类X
的类Top
,并且Foo
期望关键字参数Foo
:bar
将最终在尚未删除X(1, 2, 3, bar=5)
的情况下调用Top.__init__
。将bar
与__init__
一起使用时,关键字参数是一个很好的主意。)
super
答案 1 :(得分:1)
您需要做的是在Top
(父/基)类中包含if语句:
class Top:
def __init__(self, optional=None):
if optional is not None:
self.optional = optional
# (you don’t need an explicit return in __init__)
class Middle(Top):
def __init__(self, one, optional=None):
super().__init__(optional)
self.one = one
# this applies to Bottom class as well
现在,是否提供此可选选项都无关紧要。假设您调用Middle
时没有任何可选操作,则one
属性设置为预期值,而Top.__init__
的调用方式为None
,因为Middle
中的默认参数将其设置为如果没有提供的话。由于所有类的参数默认值均为None
,因此本质上会传递可选参数的存在(或不存在)。
就我个人而言,我什至不包括if语句。我会将属性设置为None
,以便在以后的代码中,如果您尝试访问obj.optional
,则不会引发AttributeError
。我认为,如果子类继承了属性,则应该通过子类保持属性的一致性,以便尝试使用子类的任何人都希望__init__
中使用的所有参数都可以通过众多super()
调用继承链来使用或设置为属性。并没有丢失。