Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用于更干净继承的嵌套类?_Python_Oop - Fatal编程技术网

Python 用于更干净继承的嵌套类?

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

假设我有一个BigObject类,其中包含许多SmallObject,这是使用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)]
我们必须创建一组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似乎能够自己做出这些实施决策。我提供了一个很好的替代他目前的方法。