1

In python I am able to access the variable in outer function from the inner function and hence it forms a closure. However, I am not able to access a variable in outer class from the inner class like this,

>>> class A:
...  a=1
...  class B:
...    b=1
...    def pr(self):
...     print a,b
...
>>> c=A().B()
>>> c.pr()
    Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in pr
NameError: global name 'a' is not defined

Why is this kind of closure not possible in python?

Vivek S
  • 5,384
  • 8
  • 51
  • 72
  • The short answer is: Because class scope is weird. –  Oct 07 '13 at 11:46
  • You can also get this error with one class: [example](http://pastebin.com/TmJd6Q7J). So it's probably not a classes-within-classes issue. – Kevin Oct 07 '13 at 11:48
  • @delnan I have already seen quite a number of questions that asked about this. Maybe it's time to open an "How do class scopes work in python?" CW question and use it to close all these duplicates. However, there are already some question with good answers, such as [this](http://stackoverflow.com/a/18864212/510937)(although not 100% complete), but the title of the question is misleading and hence it isn't often used to close duplicates. – Bakuriu Oct 07 '13 at 12:19

2 Answers2

2

The docs say:

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

The scope of the class block also does not extend to the code blocks of nested class statements.


It's not clear (to me) what you are trying to do, but here is a more typical pattern which makes B a subclass of A and thus allows instances of B to access attributes of both B and A:

class A:
    a=1

class B(A):
    b=1
    def pr(self):
        print self.a, self.b

c = B()
c.pr()

prints

1 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
1

You can access those class variables, but only if you qualify each with the name of the class it is defined in:

class A:
    a=1
    class B:
        b=1
        def pr(self):
            print A.a, A.B.b

c=A().B()
c.pr()

Result:

1 1
Kevin
  • 74,910
  • 12
  • 133
  • 166