import abc
class Human(object):
__metaclass__ = abc.ABCMeta
config = {
'num_ears': 2,
'num_hands': 2,
}
def __init__(self):
self.config = dict(self.config.items() + self.derived_config.items())
@abc.abstractproperty
def derived_config(self):
pass
# logic that does stuff with self.config
class Clown(Human):
derived_config = {
'funny': True,
'smile': True,
}
def __init__(self, *args, **kwargs):
self.derived_config = dict(self.derived_config.items() + self.implementation_config.items())
super(Clown, self).__init__(*args, **kwargs)
@abc.abstractproperty
def implementation_config(self):
pass
# logic that does stuff with self.config
class OneHandedClown(Clown):
implementation_config = {
'smile': False,
'num_jokes': 20,
'num_hands': 1,
}
if __name__ == '__main__':
s = OneHandedClown()
print s.config # {'funny': True, 'num_hands': 1, 'num_jokes': 20, 'num_ears': 2, 'smile': False}
我想明确指出,derived_config
属性对于Human的派生类是必需的,而抽象属性装饰器可以解决这个问题,即派生类不设置的代码这个属性不会运行。
但是pylint因以下错误而失败:
W: 39, 0: Method 'derived_config' is abstract in class 'Human' but is not overridden (abstract-method)
NB:
implementation_config
,但模式是相同的(除了OneHandedClown
是终端叶子)。 OneHandedClown
中的类变量implementation_config,如何在不使用pylint-disable
的情况下确保lint通过,同时使用abstract属性来确保继承契约是显式的?
答案 0 :(得分:1)
我找到了解决方案,但没有答案。
...
class Clown(Human):
clown_config = {
'funny': True,
'smile': True,
}
@property
def derived_config(self):
return dict(self.clown_config.items() + self.implementation_config.items())
@abc.abstractproperty
def implementation_config(self):
pass
# logic that does stuff with self.config
...
特别是,为什么设置类变量implementation_config
足以在Clown
中实现抽象属性,但derived_config
中Clown
的先前实现不足以实现Human
中的相应抽象属性?