trouble with nested closures: one of my variables is missing...

Cameron Simpson cs at zip.com.au
Sun Oct 14 17:54:02 EDT 2012


On 13Oct2012 22:07, Chris Rebert <clp2 at rebertia.com> wrote:
| On Saturday, October 13, 2012, Cameron Simpson wrote:
| > I'm having some trouble with closures when defining a decorator.
| <snip>
| 
| > However, I can't make my make_file_property function work. I've stripped
| > the code down and it does this:
| <snip>
| 
| >   Traceback (most recent call last):
| >     File "foo.py", line 21, in <module>
| >       def f(self, foo=1):
| >     File "foo.py", line 4, in file_property
| >       return make_file_property()(func)
| >     File "foo.py", line 10, in made_file_property
| >       if attr_name is None:
| >   UnboundLocalError: local variable 'attr_name' referenced before
| > assignment
| >
| > Observe above that 'unset_object' is in locals(), but not 'attr_name'.
| > This surprises me.
| >
| > The stripped back code (missing the internals of the file property
| > watcher) looks like this:
| >
| >   import sys
| >
| >   def file_property(func):
| >     return make_file_property()(func)
| >
| >   def make_file_property(attr_name=None, unset_object=None, poll_rate=1):
| >     print >>sys.stderr, "make_file_property(attr_name=%r, unset_object=%r,
| > poll_rate=%r): locals()=%r" % (attr_name, unset_object, poll_rate,locals())
| >     def made_file_property(func):
| 
| You're missing a "nonlocal" declaration here.
| 
|       print >>sys.stderr, "made_file_property(func=%r): locals()=%r" %
| > (func, locals())
| >       if attr_name is None:
| >         attr_name = '_' + func.__name__
| 
| 
|  You assign to it, but there's no nonlocal declaration, so Python thinks
| it's a local var, hence your error.

But 'unset_object' is in locals(). Why one and not the other?
Obviously there's something about closures here I'm missing.

| Pardon my brevity and some lack of trimming; I'm on a smartphone and in a
| rush.

No worries. Thansk for the rpely.
-- 
Cameron Simpson <cs at zip.com.au>

A clean desk is the sign of a blank mind.



More information about the Python-list mailing list