在子类中扩展类属性的简洁方法

Nad*_*mli 16 python

假设我有以下课程

class Parent(object):
    Options = {
        'option1': 'value1',
        'option2': 'value2'
    }
Run Code Online (Sandbox Code Playgroud)

还有一个名为Child的子类

class Child(Parent):
   Options = Parent.Options.copy()
   Options.update({
        'option2': 'value2',
        'option3': 'value3'
   })
Run Code Online (Sandbox Code Playgroud)

我希望能够覆盖或添加子类中的选项.我正在使用的解决方案.但我确信有更好的方法.


编辑

我不想将选项添加为类属性,因为我有其他类属性不是选项,我更喜欢将所有选项保存在一个地方.这只是一个简单的例子,实际代码比这更复杂.

Ale*_*lli 21

在语义上等同于您的代码,但可以说是更整洁:

class Child(Parent):
   Options = dict(Parent.Options,
      option2='value2',
      option3='value3')
Run Code Online (Sandbox Code Playgroud)

请记住,"没有大括号的生活会更好",并且通过dict明确调用,您可以经常避免使用大括号(以及类似于常量标识符的字符串的键周围的额外引号).

有关更多详细信息,请参阅http://docs.python.org/library/stdtypes.html#dict-关键位是"如果在位置参数和关键字参数中都指定了键,则与关键字关联的值保留",即关键字args 覆盖位置arg中的键值关联,就像update方法允许您覆盖它们一样).


Ant*_*sma 8

一种方法是使用dict的关键字参数来指定其他键:

Parent.options = dict(
    option1='value1',
    option2='value2',
)

Child.options = dict(Parent.options,
    option2='value2a',
    option3='value3',
)
Run Code Online (Sandbox Code Playgroud)

如果您想获得更好的功能,那么使用描述符协议可以创建一个封装查找的代理对象.(只需将所有者.__ mro__从owner属性转到__get __(self,instance,owner)方法).甚至更高级,进入可能不是一个好主意的领域,元类/类装饰器.


Nad*_*mli 6

在仔细考虑之后,感谢@SpliFF的建议,这就是我想出来的:

class Parent(object):
    class Options:
        option1 = 'value1'
        option2 = 'value2'


class Child(Parent):
    class Options(Parent.Options):
        option2 = 'value2'
        option3 = 'value3'
Run Code Online (Sandbox Code Playgroud)

我仍然愿意接受更好的解决方案.