[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