[EMAIL PROTECTED] wrote:
On Nov 6, 9:57 pm, mrstevegross <[EMAIL PROTECTED]> 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.

So do that.

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

Interpreter global namespace == builtins

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 :) )

Correct

Try this ..

Why?

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

This create a duplicate Inner class object for every instance of Outer, which is almost certainly not what the OP wants.

Outer()

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

tjr

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to