2008-09-17 78 views
73

我在这里讨论的是嵌套类。基本上,我有两个我正在建模的类。 DownloadManager类和DownloadThread类。这里明显的OOP概念是组合。但是,构图并不一定意味着嵌套,对吧?在Python的另一个类中定义一个类是否有好处?

我有一些代码看起来是这样的:

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

回答

97

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

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

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

唯一的其他时间我使用嵌套类一样的是,我使用的外部类只能作为一个命名空间组一堆密切相关的类在一起:

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

    class cls2(object): 
     ... 
从另一个模块

然后,您可以导入组,并将其称为Group.cls1,Group.cls2等。但是,有人可能会争辩说,通过使用模块,您可以完全相同(也许以一种不太令人困惑的方式)。

+9

我-would-认为,在第二种情况下,你会-definitely-使用一个模块或包,它被设计为命名空间得到更好的服务。 – 2008-09-17 03:51:33

+3

这是一个梦幻般的答案。简单点,并提到使用模块的替代方法。 +1 – CornSmith 2013-05-08 16:19:44

+5

为了记录,对于那些固执地拒绝或不能将他们的代码组织到分层包和适当模块中的人来说,使用类作为名称空间有时可能比不使用任何东西更好。 – 2014-04-07 19:05:57

1

不,构图并不意味着嵌套。 如果要将其隐藏在外部类的名称空间中,则需要嵌套类。

无论如何,我没有看到你的情况下嵌套的任何实际用途。它会使代码更难阅读(理解),并且还会增加缩进,这会使行数更短,更易于分裂。

16

我不知道Python,但你的问题似乎很普遍。如果它特定于Python,请忽略我。

类嵌套是关于范围。如果你认为一个类只在另一个类的背景下才有意义,那么前者可能是成为嵌套类的好候选者。

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

4

您可能会使用类作为类生成器。赞(在一些即兴代码:)

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

这样做真的没有好处,除非你正在处理元类。

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

的名称,字典和基地都传递给作为元类的功能,则在其中类范围赋值给变量“名”:一套了。

你可以通过混淆元类,甚至通过在你的库存标准类中嵌套类获得什么,很难阅读代码,难以理解代码,以及难以理解的奇怪错误, 'class'作用域与其他python作用域完全不同。

相关问题