On Wed, Apr 13, 2011 at 3:12 AM, Larry Hastings <la...@hastings.org> wrote:
> > The problem: if you're currently in a nested class, you can't look up > variables in the outer "class scope". > > For example, this code fails in Python 3: > > class Outer: > class Inner: > class Worker: > pass > > class InnerSubclass(Inner): > class Worker(Inner.Worker): > pass > > It fails at the definition of Worker inside InnerSubclass. Python 3 can't > find "Inner", in order to get to "Inner.Worker". > > Adding "global Inner" just above that line doesn't help--it's not a global. > Adding "nonlocal Inner" just above that line doesn't help either--I suppose > it's the *wrong kind* of nonlocal. nonlocal is for nested functions, and > this uses nested classes. > > You can tell me YAGNI, but I tripped over this because I wanted it. It's > not a contrived example. I actually use inner classes a lot; I suppose I'm > relatively alone in doing so. > > Yes, I could make the problem go away if I didn't have nested inner classes > like this. But I like this structure. Any idea how I can make it work > while preserving the nesting and inheritance? > Hi Larry, My understanding is that the problem revolves around how classes are built. The body of the inner class has access to itself and to the globals, and to whatever locals may be around (if defined inside a function). So if you want to see something, you have to put it in one of those. I suppose you could try something like this: class Outer: global Inner class Inner: class Worker: pass class InnerSubclass(Inner): class Worker(Inner.Worker): pass However, that pollutes your global namespace. If you are worried about that you could try: def namespaces(): Inner = None class Outer: nonlocal Inner class Inner: class Worker: pass class InnerSubclass(Inner): class Worker(Inner.Worker): pass return Outer However, this freaks out because Inner does not get bound to Outer, even though it is available to Worker. You can use function locals but you lose your clean nesting: def namespaces(): class Something: pass class Outer: class Inner: class Worker: pass class InnerSubclass(Inner): class Worker(Something): pass return Outer Anyway, definitely a weird problem. Maybe the class body should be able to access the namespaces that wrap it, like functions do... Not that I have found them, but I would not be surprised if there have been plenty of discussions around class body namespaces and nesting and closure... It would be great if it just worked, or at the very least you could do something like this: class Outer: class Inner: class Worker: pass class InnerSubclass(Inner): nonlocal Inner class Worker(Inner.Worker): pass return Outer That would pull Inner into the namespace of InnerSubclass, allowing Worker to use it in the bases declaration. If you really want to get crazy, I suppose you could do so metaclass hackery... -eric > Thanks, > > > *larry* > ** > > -- > http://mail.python.org/mailman/listinfo/python-list > >
-- http://mail.python.org/mailman/listinfo/python-list