I'm trying to understand scope in nested classes in Python. Here is my example code:
class OuterClass:
outer_var = 1
class InnerClass:
inner_var = outer_var
The creation of class does not complete and I get the error:
<type 'exceptions.NameError'>: name 'outer_var' is not defined
Trying inner_var = Outerclass.outer_var
doesn't work.
I get:
<type 'exceptions.NameError'>: name 'OuterClass' is not defined
I am trying to access the static outer_var
from InnerClass
.
Is there a way to do this?
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 nameOuter
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 anOuter
becauseouter_var
is really an instance attribute: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
toInner
, if you want.)All explanations can be found in Python Documentation The Python Tutorial
For your first error
<type 'exceptions.NameError'>: name 'outer_var' is not defined
. The explanation is:quoted from The Python Tutorial 9.4
For your second error
<type 'exceptions.NameError'>: name 'OuterClass' is not defined
quoted from The Python Tutorial 9.3.1
So when you try
inner_var = Outerclass.outer_var
, theQuterclass
hasn't been created yet, that's whyname 'OuterClass' is not defined
A more detailed but tedious explanation for your first error:
quoted from Learning.Python(5th).Mark.Lutz
You might be better off if you just don't use nested classes. If you must nest, try this:
Or declare both classes before nesting them:
(After this you can
del InnerClass
if you need to.)I think you can simply do:
The problem you encountered is due to this:
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.
Easiest solution:
It requires you to be explicit, but doesn't take much effort.
In Python mutable objects are passed as reference, so you can pass a reference of the outer class to the inner class.