带有可选参数的继承链

Inheritance chain with optional parameter

我想要一个继承链有一个可选参数。链上的大多数 classes 有时需要 参数成为成员 ,但我也想在其他时候使用链 而无需参数成为成员成员

我考虑过将参数设为可选的 class 并使用导入,但我想避免对成员 optional 使用 class 语法。也因为链上的所有 classes 在字典中用作键。

这个的替代品?难道我做错了什么?有没有更 Pythonic 的方式?

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')

Top已经知道如何处理optional=None;只需按原样传递参数。但是,请记住,每个 class 都必须准备好接收和传递未知参数,以防您未定义的 class 继承其中任何一个并添加其 拥有 __init__ 个参数 个。 (考虑从 Top 和其他一些 class Foo 继承的 class X,并且 Foo 需要关键字参数 bar: X(1, 2, 3, bar=5) 最终会调用 Top.__init__bar 还没有被移除。当使用 __init__super 时关键字参数是一个非常好的主意。)

class Top:

    def __init__(self, optional=None, **kwargs):
        super().__init__(**kwargs)
        if optional is not None:
            self.optional = optional


class Middle(Top):

    def __init__(self, one, optional=None, **kwargs):
        super().__init__(optional, **kwargs)
        self.one = one


class Bottom(Middle):

    def __init__(self, one, two, optional=None, **kwargs):
        super().__init__(one, optional, **kwargs)    
        self.two = two

您只需要在 Top (parent/base) class:

中包含 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

现在你是否提供这个选项已经无关紧要了。假设您在没有可选的情况下调用 Middleone 属性按预期设置并且 Top.__init__ 使用 None 调用,因为 Middle 中的默认参数将其设置为这个如果没有提供。由于您的参数默认值在所有 class 中都是 None ,因此本质上可以执行可选的存在(或不存在)。

就我个人而言,我什至不会包含 if 语句。我会将该属性设置为 None,以便稍后在您的代码中尝试访问 obj.optional 时,不会引发 AttributeError。我相信如果属性是继承的,应该通过 subclasses 保持属性一致,这样任何试图使用 subclasses 的人都期望 __init__ 中使用的所有参数都被使用或设置为属性无数的 super() 调用了继承链并且没有丢失。