On Thu, Jul 27, 2006 at 12:46:44PM -0400, Kent Johnson wrote:
> Dave Kuhlman wrote:
> > I've written up a few notes on Python namespaces and scopes. If
> > anyone has corrections, comments, or suggestions, I'd appreciate
> > them. You can find my comments here:
> >
> > http://www.rexx.com/~dkuhlman/python_comments.html#namespaces
>
> You wrote, "If a variable is assigned a value /anywhere/ in a scope
> (...), then that variable is local to that scope. Otherwise, the
> variable is global."
>
> You omit the enclosing scope and the builtin namespace. A variable can
> be defined in
> - local scope
> - any of zero or more enclosing scopes
> - global scope
> - builtin namespace
Thanks. I've added the built-in namespace to my notes.
But, I don't believe in the existence of nested namespaces. I
think they are a hoax. Some people believe that nested namespaces
were added sometime around Python 2.1 or 2.2. But, that's just a
fraud. If there were really such a thing as nested
scopes/namespaces, we would have a function that would give us
access to them, similar to the way that locals() and globals()
give us access to the local and global namespace.
>
> Names are also bound by for statements and except clauses.
Right. I've added that, now.
>
> You might note that augmented assignment (e.g. a += 1) counts as
> assignment in the local scope. This is a common cause of UnboundLocalError:
>
> In [5]: a=1
>
> In [6]: def foo():
> ...: a+=1
> ...:
> ...:
>
> In [7]: foo()
> ---------------------------------------------------------------------------
> exceptions.UnboundLocalError Traceback (most
> recent call last)
>
> D:\Projects\e3po\<ipython console>
>
> D:\Projects\e3po\<ipython console> in foo()
>
> UnboundLocalError: local variable 'a' referenced before assignment
>
>
> I think modifying globals() is guaranteed to work. Modifying locals()
> only works at global scope, i.e. when locals() is globals().
>
> You wrote, "Note that for lexically/statically nested scopes (for
> example, a function defined inside a function), it seems that globals()
> and locals() still give access to all items in the accessible
> namespaces." I'm not sure what you mean by this. locals() doesn't give
> access to items in nested scopes:
>
You are right. I'm confused about this. But, it is Python's
fault. See more below.
> In [1]: x=1
>
> In [2]: def maker():
> ...: y=2
> ...: def showLocals():
> ...: z=3
> ...: print locals()
> ...: return showLocals
> ...:
>
> In [3]: sl=maker()
>
> In [4]: sl()
> {'z': 3}
>
Oh yeah? Well, what about this?
In [1]: def maker():
...: y=2
...: def showLocals():
...: z=3
...: keys = locals().keys()
...: keys.sort()
...: print 'locals:', keys
...: keys = globals().keys()
...: keys.sort()
...: print 'globals:', keys
...: return showLocals
...:
In [2]: sl = maker()
In [3]: sl()
locals: ['z']
globals: ['In', 'Out', '_', '__', '__IP', '___', '__builtins__',
'__name__', '__nonzero__', '_dh', '_i', '_i0', '_i1', '_i2',
'_i3', '_ih', '_ii', '_iii', '_oh', 'help', 'maker', 'sl']
So, were is y? See, nested scopes do not exist.
> See also
> http://docs.python.org/ref/naming.html
>
OK. Trying to be a little more serious ... Maybe Python now
*does* have nested scopes, but Python does not give us a function
to access them. Or does it?
Thanks again for the help.
Dave
--
Dave Kuhlman
http://www.rexx.com/~dkuhlman
_______________________________________________
Tutor maillist - [email protected]
http://mail.python.org/mailman/listinfo/tutor