it-swarm.cn

在Python的中定义另一个类中的类有什么好处?

我在这里谈论的是嵌套类。基本上,我有两个我正在建模的类。 DownloadManager类和DownloadThread类。这里显而易见的OOP概念就是构图。然而,构图并不一定意味着嵌套,对吧?

我的代码看起来像这样:

class DownloadThread:
    def foo(self):
        pass

class DownloadManager():
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadThread())

但现在我想知道是否存在嵌套会更好的情况。就像是:

class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
88
fuentesjr

当“内部”类是一次性的时,你可能想要这样做,它永远不会在外部类的 definition 之外使用。例如,要使用元类,它有时候很方便

class Foo(object):
    class __metaclass__(type):
        .... 

如果您只使用一次,而不是单独定义元类。

我唯一一次使用这样的嵌套类,我只使用外部类作为命名空间将一堆密切相关的类组合在一起:

class Group(object):
    class cls1(object):
       ...

    class cls2(object):
       ...

然后从另一个模块,你可以导入Group并将它们称为Group.cls1,Group.cls2等。但是有人可能会说你可以通过使用模块完成相同的工作(可能以一种不那么混乱的方式)。

106
dF.

我不懂Python,但你的问题似乎很笼统。如果它特定于Python,请忽略我。

类嵌套完全是关于范围的。如果你认为一个类只在另一个类的上下文中有意义,那么前者可能是成为嵌套类的一个很好的候选者。

这是一个常见的模式,将辅助类作为私有嵌套类。

19
André Chalella

除非您正在处理元类,否则执行此操作确实没有任何好处。

班级:套房真的不是你想象的那样。这是一个奇怪的范围,它做了奇怪的事情。它真的甚至不上课!它只是收集一些变量的一种方式 - 类的名称,基础,属性的小字典和元类。

名称,字典和基数都传递给元类的函数,然后将它分配给类:suite所在范围内的变量“name”。

通过弄乱元类,实际上通过在库存标准类中嵌套类,你可以获得什么,更难以阅读代码,更难理解代码,以及奇怪的错误,如果不熟悉“类”的原因,这些错误非常难以理解scope与任何其他python范围完全不同。

6
Jerub

您可以使用类作为类生成器。喜欢(在一些袖口代码:)

class gen(object):
    class base_1(object): pass
    ...
    class base_n(object): pass

    def __init__(self, ...):
        ...
    def mk_cls(self, ..., type):
        '''makes a class based on the type passed in, the current state of
           the class, and the other inputs to the method'''

我觉得当你需要这个功能时,你会非常清楚。如果你不需要做类似的事情,它可能不是一个好的用例。

5
tim.tadh

当需要构建其增强功能封装在特定嵌套类中的继承类时,嵌套类还有另一种用法。

看这个例子:

__码__

请注意,在foo的构造函数中,当正在构造的对象实际上是foo对象时,self.a = self.bar()行将构造class foo: class bar: ... # functionalities of a specific sub-feature of foo def __init__(self): self.a = self.bar() ... ... # other features of foo class foo2(foo): class bar(foo.bar): ... # enhanced functionalities for this specific feature def __init__(self): foo.__init__(self) ,而当构造的对象实际上是foo.bar对象时,foo2.bar对象将构造foo2

如果类bar在类foo之外被定义,以及它的继承版本(例如,它将被称为bar2),那么定义新类foo2将会更加痛苦,因为foo2的构造函数需要拥有它第一行替换为self.a = bar2(),这意味着重写整个构造函数。

4
Thomas

不,构图并不意味着嵌套。如果要在外部类的命名空间中更多地隐藏它,那么有一个嵌套类是有意义的。

无论如何,我认为在你的情况下没有任何实际的嵌套用法。这将使代码更难以阅读(理解),并且它还会增加缩进,这会使行更短并且更容易分裂。

1
Cristian Ciupitu