具有 class 继承的 kwargs 中的默认值

Default values in kwargs with class inheritance

我有两个 类 AB(A)。他们的构造函数接受 style 字典作为关键字参数。

对于我想要的 A 个对象,默认情况下,字符串 green 关联到 style['color']

对于 B 个对象 color 默认为 red

我想到了这个解决方案,但发现它相当笨拙。有没有更优雅的方法来做到这一点?

class A:
    def __init__(self, **kwargs):
        style = kwargs.pop('style', {})
        if 'color' not in style:
            style['color'] = 'green'
        print(style)

class B(A):
    def __init__(self, **kwargs):
        style = kwargs.pop('style', {})
        if 'color' not in style:
            style['color'] = 'red'
        super().__init__(style=style, **kwargs)

A()  #  {'color': 'green'}
B()  #  {'color': 'red'}
B(style={'color': 'blue'})  #  {'color': 'blue'}

试试下面的方法。

它向基础 class 引入了一个名为 default_kwarg 的辅助方法。

在两种情况下(superclass 和 subclass)都可以调用它来设置 color 键的默认值。

这种方法还使 style 字典能够包含其他 key/value 对。我在最后添加了一个额外的例子来证明这一点。

class A:
    def default_kwarg(self, arg, default):
        arg = arg.pop('style', {})
        if 'color' not in arg:
          arg['color'] = default
        return arg

    def __init__(self, **kwargs):
        style = self.default_kwarg(kwargs, 'green')
        print(style)

class B(A):
    def __init__(self, **kwargs):
        kwargs['style'] = self.default_kwarg(kwargs, 'red')
        super().__init__(**kwargs)

A()  #  {'color': 'green'}
B()  #  {'color': 'red'}
B(style={'color': 'blue'})  #  {'color': 'blue'}
B(style={'something': 'else'})  #  {'something': 'else', 'color': 'red'}

您还可以很容易地推广此辅助方法,以将默认值应用于字典中的其他键。

这看起来稍微干净一些,但感觉还是有点老套:

class A:
    def __init__(self, **kwargs):
        self.style = kwargs.get('style', {'color': 'green'})
        print(self.style)

class B(A):
    def __init__(self, **kwargs):
        kwargs['style'] = kwargs.get('style', {'color': 'red'})
        super().__init__(**kwargs)

A()  #  {'color': 'green'}
B()  #  {'color': 'red'}
B(style={'color': 'blue'})

如果 style 实际上是 self.style,我假设它是,您可以将分配委托给父级 class,因为它总是通过 [=14= 到达那里] 反正

这假设之后没有尝试从 kwargs 中提取 'style'。您不需要,因为它已经分配给 self.style.

您可能注意到,如果您传入 style 但不为其分配 'color',它也会失败。如果您打算这样做,最好将 color 设置为默认关键字参数。

class A:
    def __init__(self, color='green', **kwargs):
        self.style = kwargs.get('style', {'color': color})
        self.style['color'] = self.style.get('color', color)
        print(self.style)

class B(A):
    def __init__(self, color='red', **kwargs):
        kwargs['style'] = kwargs.get('style', {'color': color})
        super().__init__(color=color, **kwargs)

A()  #  {'color': 'green'}
B()  #  {'color': 'red'}
B(style={'font': 'Times New Roman'})  #  {'color': 'red'}
B(style={'color': 'blue'})