带有可选参数的继承链

时间:2019-01-05 15:40:58

标签: python python-3.x optional-parameters

我希望继承链具有可选参数。链中的大多数类有时都需要使参数成为成员,但是我也想在其他时间使用链而不使参数成为成员。

我曾考虑过将参数设为可选类并使用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')

2 个答案:

答案 0 :(得分:1)

Top已经知道如何处理optional=None;照原样传递参数。但是,请记住,每个类都必须准备好接收并传递未知参数,以防万一您未定义的类继承自其中任何一个并将其 own 参数添加到{{1 }}。 (请考虑一个同时继承自__init__和某个其他类X的类Top,并且Foo期望关键字参数Foobar将最终在尚未删除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()调用继承链来使用或设置为属性。并没有丢失。