Nested classes' scope? Nested classes' scope? python python

Nested classes' scope?


class Outer(object):    outer_var = 1    class Inner(object):        @property        def inner_var(self):            return Outer.outer_var

This isn't quite the same as similar things work in other languages, and uses global lookup instead of scoping the access to outer_var. (If you change what object the name Outer is bound to, then this code will use that object the next time it is executed.)

If you instead want all Inner objects to have a reference to an Outer because outer_var is really an instance attribute:

class Outer(object):    def __init__(self):        self.outer_var = 1    def get_inner(self):        return self.Inner(self)        # "self.Inner" is because Inner is a class attribute of this class        # "Outer.Inner" would also work, or move Inner to global scope        # and then just use "Inner"    class Inner(object):        def __init__(self, outer):            self.outer = outer        @property        def inner_var(self):            return self.outer.outer_var

Note that nesting classes is somewhat uncommon in Python, and doesn't automatically imply any sort of special relationship between the classes. You're better off not nesting. (You can still set a class attribute on Outer to Inner, if you want.)


I think you can simply do:

class OuterClass:    outer_var = 1    class InnerClass:        pass    InnerClass.inner_var = outer_var

The problem you encountered is due to this:

A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition.
(...)
A scope defines the visibility of a name within a block.
(...)
The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes generator expressions since they are implemented using a function scope. This means that the following will fail:

   class A:         a = 42         b = list(a + i for i in range(10))

http://docs.python.org/reference/executionmodel.html#naming-and-binding

The above means:
a function body is a code block and a method is a function, then names defined out of the function body present in a class definition do not extend to the function body.

Paraphrasing this for your case:
a class definition is a code block, then names defined out of the inner class definition present in an outer class definition do not extend to the inner class definition.


You might be better off if you just don't use nested classes. If you must nest, try this:

x = 1class OuterClass:    outer_var = x    class InnerClass:        inner_var = x

Or declare both classes before nesting them:

class OuterClass:    outer_var = 1class InnerClass:    inner_var = OuterClass.outer_varOuterClass.InnerClass = InnerClass

(After this you can del InnerClass if you need to.)