The problem here is not the definition order, which works like everything else, it is the special nature of class-body scope. Essentially, variables in the class-body scope can only be accessed using the class-namespace, e.g. MyClass.my_class_variable
. The special aspect of it is that it does not create an enclosing scope, which is why you cannot access my_class_variable
and are forced to use the class-namespace inside a method definition, for example. Read more about that in this answer. So again, B
is in fact defined. Note, the following works:
In [4]: class A:
...: class B:
...: pass
...: x = B.__name__
...:
...:
In [5]: A.x
Out[5]: 'B'
Now, you might hope the following would work:
In [6]: class A:
...: class B:
...: pass
...: class C:
...: x = A.B()
...:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-a145c80eee84> in <module>()
----> 1 class A:
2 class B:
3 pass
4 class C:
5 x = A.B()
<ipython-input-1-a145c80eee84> in A()
2 class B:
3 pass
----> 4 class C:
5 x = A.B()
6
<ipython-input-1-a145c80eee84> in C()
3 pass
4 class C:
----> 5 x = A.B()
6
However, it does not, because A
hasn't actually been defined yet! So, the solution is something like this:
In [7]: class A:
...: class B:
...: pass
...: class C:
...: pass
...:
...:
In [8]: A.C.x = A.B
Edited
So, this example should be illuminating:
In [14]: x = 'global'
In [15]: class Foo:
...: x = 'foooooo!'
...: def bar(self):
...: return x
...:
In [16]: Foo().bar()
Out[16]: 'global'
In [17]: Foo.x
Out[17]: 'foooooo!'