嵌套类以获得更干净的继承?

时间:2018-09-24 13:22:09

标签: python oop

说我有一个BigObject类,其中包含许多SmallObjects-这是使用SmallObject的唯一地方。

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)]

我们只需要创建一堆SmallObjects即可立即用NewSmallObjects覆盖它们。如果例如,这不是很好SmallObjects创建起来很昂贵。另外,如果我们更改在BigObject中创建SmallObjects列表的方式,则这些更改不会传递给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(包含MinisculeObjects等),它也可以创建非常深层的嵌套类。

所以我的问题基本上是:

  • 这是解决此问题的“好方法”吗?

  • 如果不是,一个好的替代方案是什么?

2 个答案:

答案 0 :(得分:1)

您已经发现,解决方案是将SmallObject设为BigObject类的属性。

为此使用嵌套类并没有天生的错误,但是如果嵌套类很长,则代码的可读性可能会受到影响。一般来说,尽管如此,我还是建议在全局范围内定义SmallObject。毕竟,the Zen of Python说“扁平比嵌套更好”。如果继续嵌套TinyObjectMinisculeObject,您的代码将很快变得不可读:

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

答案 1 :(得分:0)

这似乎是Abstract Factory模式的好用例。

要点是,存在一个类层次结构,用于创建从SmallObject派生的事物。这样,BigObject的子类都将使用相同的接口来获取其SmallObject实例。