Python 用于更干净继承的嵌套类?
假设我有一个BigObject类,其中包含许多SmallObject,这是使用SmallObject的唯一地方Python 用于更干净继承的嵌套类?,python,oop,Python,Oop,假设我有一个BigObject类,其中包含许多SmallObject,这是使用SmallObject的唯一地方 class SmallObject: pass class BigObject: def __init__(self): self.objects = [SmallObject() for _ in range(10)] 这一切都很好,直到我想要这两个的第二个版本,它继承了一些行为并覆盖了一些;继承似乎很自然,除了: class NewSmallOb
class SmallObject:
pass
class BigObject:
def __init__(self):
self.objects = [SmallObject() for _ in range(10)]
这一切都很好,直到我想要这两个的第二个版本,它继承了一些行为并覆盖了一些;继承似乎很自然,除了:
class NewSmallObject(SmallObject):
pass
class NewBigObject(BigObject):
def __init__(self):
super().__init__()
self.objects = [NewSmallObject for _ in range(10)]
我们必须创建一组SmallObject,然后立即用NewSmallObjects覆盖它们。如果创建小型对象的成本很高,这就不太好了。此外,如果我们更改在BigObject中创建SmallObject列表的方式,这些更改不会传递给NewBigObject
我提出的解决方案是使用嵌套类:
class BigObject:
class SmallObject:
pass
def __init__(self):
self.objects = [self.SmallObject() for _ in range(10)]
class NewBigObject(BigObject):
class SmallObject(BigObject.SmallObject):
pass
这涉及上述两个问题。我主要关心的是,当我在StackOverflow上查找有关Python中嵌套类的问题时,人们总是说嵌套类是非Python的,我想了解原因。如果SmallObject包含TinyObjects,而TinyObjects包含MinimizeObject等,那么它还可以创建嵌套非常深的类,这可能就是答案
所以我的问题基本上是:
- 这是解决这个问题的“好”办法吗
- 如果不是,那么好的替代方案是什么
要点是有一个类层次结构,用于创建从
SmallObject
派生的东西。这样,BigObject
的子类都将使用相同的接口来获取它们的SmallObject
实例。解决方案是,正如您已经发现的,将SmallObject
作为BigObject
类的属性
为此使用嵌套类本身没有什么错误,但是如果嵌套类很长,代码的可读性可能会受到影响。一般来说,我建议在全局范围内定义SmallObject
。毕竟,他说“扁平比嵌套好”。如果继续嵌套TinyObject
s和minimizeobject
s,代码将很快变得不可读:
class BigObject:
class SmallObject:
class TinyObject:
class MinisculeObject:
... # MinisculeObject class body
... # TinyObject class body
... # SmallObject class body
... # BigObject class body
在全局范围内定义类只需要很少的额外工作,而且看起来更干净:
class MinisculeObject:
... # MinisculeObject class body
class TinyObject:
miniscule_object_factory = MinisculeObject
... # TinyObject class body
class SmallObject:
tiny_object_factory = TinyObject
... # SmallObject class body
class BigObject:
small_object_factory = SmallObject
... # BigObject class body
我认为解释一下如何使用这种模式会更有用。在python中,不需要所有的
SmallObject
s从公共基类继承,也不需要工厂(因为类本身就是工厂)。我认为当你说OP应该使用抽象工厂模式时,你并没有告诉他们任何新的东西,因为很明显他们需要不同的SmallObject
类和实例化它们的方法。在我看来,问题更多的是关于该模式的正确应用。OP似乎能够自己做出这些实施决策。我提供了一个很好的替代他目前的方法。