tags:

views:

2055

answers:

5

So what i'm talking about here are nested classes. So essentially I have two classes that I'm modeling. I have a DownloadManager class and a DownloadThread class. The obvious OOP concept here is composition. However, composition doesn't necessarily mean nesting, right?

So I have code that looks something like this:

class DownloadThread:
    def foo(self):
        pass

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

But now I'm wondering if there's a situation where nesting would be better. Something like:

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

No, composition does not mean nesting. It would make sense to have a nested class if you want to hide it more in the namespace of the outer class.

Anyway, I don't see any practical use for nesting in your case. It would make the code harder to read (understand) and it would also increase the indentation which would make the lines shorter and more prone to splitting.

Cristian Ciupitu
+11  A: 

You might want to do this when the "inner" class is a one-off, which will never be used outside the definition of the outer class. For example to use a metaclass, it's sometimes handy to do

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

instead of defining a metaclass separately, if you're only using it once.

The only other time I've used nested classes like that, I used the outer class only as a namespace to group a bunch of closely related classes together:

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

    class cls2(object):
       ...

Then from another module, you can import Group and refer to these as Group.cls1, Group.cls2 etc. However one might argue that you can accomplish exactly the same (perhaps in a less confusing way) by using a module.

dF
Also, a concealed class limits your long-term flexibility by making it harder to subclass the inner class.
S.Lott
I -would- argue that in the second case, you would -definitely- be better served using a module or package, which are designed to be namespaces.
Matthew Trevor
@SLott: how is it harder to subclass the inner class? "class Foo(Group.cls1): ..."
dF
+2  A: 

I don't know Python, but your question seems very general. Ignore me if it's specific to Python.

Class nesting is all about scope. If you think that one class will only make sense in the context of another one, then the former is probably a good candidate to become a nested class.

It is a common pattern make helper classes as private, nested classes.

André Neves
+1  A: 

You could be using a class as class generator. Like (in some off the cuff code :)

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'''

I feel like when you need this functionality it will be very clear to you. If you don't need to be doing something similar than it probably isn't a good use case.

cheers tim

tim.tadh
+1  A: 

There is really no benefit to doing this, except if you are dealing with metaclasses.

the class: suite really isn't what you think it is. It is a weird scope, and it does strange things. It really doesn't even make a class! It is just a way of collecting some variables - the name of the class, the bases, a little dictionary of attributes, and a metaclass.

The name, the dictionary and the bases are all passed to the function that is the metaclass, and then it is assigned to the variable 'name' in the scope where the class: suite was.

What you can gain by messing with metaclasses, and indeed by nesting classes within your stock standard classes, is harder to read code, harder to understand code, and odd errors that are terribly difficult to understand without being intimately familiar with why the 'class' scope is entirely different to any other python scope.

Jerub
Disagree: Nesting exception classes is very useful, because users of your class can check for your custom exceptions without having to do any messy imports. E.g. ``except myInstanceObj.CustomError, e:``
RobM
Evil, antipattern, codesmell. -1
Jerub