Weird behavior with lexical scope

saju.pillai at gmail.com saju.pillai at gmail.com
Thu Nov 6 14:26:40 EST 2008


On Nov 6, 9:57 pm, mrstevegross <mrstevegr... at gmail.com> wrote:
> I ran into a weird behavior with lexical scope in Python. I'm hoping
> someone on this forum can explain it to me.
>
> Here's the situation: I have an Outer class. In the Outer class, I
> define a nested class 'Inner' with a simple constructor. Outer's
> constructor creates an instance of Inner. The code looks like this:
>
> =========
> class Outer:
>   class Inner:
>     def __init__(self):
>       pass
>   def __init__ (self):
>     a = Inner()
> Outer()
> =========
>
> However, the above code doesn't work. The creation of Inner() fails.
> The error message looks like this:
>
>   File "/tmp/foo.py", line 12, in <module>
>     Outer()
>   File "/tmp/foo.py", line 10, in __init__
>     a = Inner()
> NameError: global name 'Inner' is not defined
>
> This surprises me! Since the construction of Inner takes place within
> the lexical scope 'Outer', I assumed the interpreter would search the
> Outer scope and find the 'Inner' symbol. But it doesn't! If I change:
>   a = Inner()
> to
>   a = Outer.Inner()
>
> it works fine, though.

AFAIK, when 'Outer.__init__' executes, 'Inner' is first searched for
within 'Outer.__init__()'s local namespace. Since 'Inner' is defined
outside the function namespace, the search will fail. Python then
looks at the module level namespace - where Inner is again not defined
(only 'Outer' is available in the module namespace), the final search
will be in the interpreter global namespace which will fail too. When
you change your code from 'Inner' to 'Outer.Inner', the module level
namespace search will match ( or atleast that's how i think it should
all work :) )

Try this ..

class Outer:
   def __init__(self):
      class Inner:
         def __init__(self): pass
      a = Inner()
Outer()

This should work, because the Outer.__init__ namespace (first
namespace being searched) has Inner defined within it

-srp



>
> So, can anyone explain to me how Python looks up symbols? It doesn't
> seem to be searching the scopes I expected...
>
> Thanks,
> --Steve




More information about the Python-list mailing list