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  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to