我最近在我的python
代码中遇到了一种奇怪的气味,我认为这与并行继承有关。下面是我编造的一个小例子:
class DogHabits:
def __init__(self):
self.habits = ['lick butt']
class GermanShepherdHabits(DogHabits):
def __init__(self):
super().__init__()
self.habits.extend(['herd sheep'])
class LabradorHabits(DogHabits):
def __init__(self):
super().__init__()
self.habits.extend(['hunt', 'pee on owner'])
class Dog:
def __init__(self):
self.type = 'generic_dog'
self.my_habits = DogHabits()
def do_stuff(self):
for habit in self.my_habits.habits:
print(habit)
class GermanShepherd(Dog):
def __init__(self):
self.type = 'german shepherd'
self.my_habits = GermanShepherdHabits()
class Labrador(Dog):
def __init__(self):
self.type = 'labrador'
self.my_habits = LabradorHabits()
if __name__ == "__main__":
german_shepherd = GermanShepherd()
print('\n{}'.format(german_shepherd.type))
german_shepherd.do_stuff()
labrador = Labrador()
print('\n{}'.format(labrador.type))
labrador.do_stuff()
我有一个通用的dog类,具体的dog实现从中继承。每个狗类(包括泛型/抽象类)都有一组习惯,其本身由另一个习惯类层次结构表示
我对两个层次结构必须始终完全相同这一事实感到恼火。此外,DogHabits
之间的继承在习惯层次结构中很有用,但在dogs层次结构中却没有用,因为我需要为dog层次结构中的每个类实例化一个单独的habits对象
什么是解药?我可能想添加许多dog类的实现,更新相应的习惯层次结构听起来很乏味,而且很难闻
如果习惯需要类属性,而不是实例属性,那么这实际上可能是元类的一个很好的用途
习惯不一定是一个简单的列表,它可以是其他的东西,只要有一个概念,除了以前的和返回新的。(
__add__
或__radd__
在一个习惯类上,我认为会达到这个效果)输出:
这个答案假设DogHabits比一个简单的列表要复杂得多,并且确实值得一个拥有自己继承的专用类
从设计的角度来看,我可以看到关于
habits
和type
应该是类成员还是实例成员的第一个问题。在这里,这个答案再次假设有理由让他们成为实例成员我将使
Habits
成为Dogs
的内部类,并在类文档中声明,可以通过在Dogs
的子类中构建它的子类来定制:这可能太离谱了,但我认为不需要单独的
DogHabits
类habits
应该是类属性,而不是实例属性,并且可以由__init_subclass__
设置type
本身更像是类属性而不是实例属性,因为它只是类本身已经编码的信息的(替代)字符串表示。由于您不会附加到现有值,因此在必要时设置class属性比通过__init_subclass
更容易:相关问题 更多 >
编程相关推荐