首页 > 解决方案 > 嵌套类以实现更清晰的继承?

问题描述

假设我有一个 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 包含包含 MinisculeObjects 等的 TinyObjects,它还可以创建非常深的嵌套类,这可能是答案?

所以我的问题基本上是:

标签: pythonoop

解决方案


正如您已经发现的那样,解决方案是创建类SmallObject的属性BigObject

为此使用嵌套类本身并没有错,但是如果嵌套类很长,代码的可读性可能会受到影响。一般来说,我建议SmallObject在全局范围内定义。毕竟,Python 之禅说“扁平胜于嵌套”。如果你不断嵌套TinyObjects 和MinisculeObjects,你的代码很快就会变得不可读:

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

推荐阅读