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

Chris Rebert clp2 at rebertia.com
Sun Oct 14 01:07:01 EDT 2012


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.

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

- Chris

      lock_name = attr_name + '_lock'
>       def getprop(self):
>         with getattr(self, lock_name):
>           # innards removed here
>           pass
>         return getattr(self, attr_name, unset_object)
>       return property(getprop)
>     return made_file_property
>
>   @file_property
>   def f(self, foo=1):
>     print "foo=%r" % (foo,)
>
>   @make_file_property(attr_name="_blah")
>   def f2(self, foo=2):
>     print "foo=%r" % (foo,)
>
> Can someone explain what I'm doing wrong, or tell me this is a python
> bug?
> --
> Cameron Simpson <cs at zip.com.au <javascript:;>>
>
> Bolts get me through times of no courage better than courage gets me
> through times of no bolts!
>         - Eric Hirst <eric at u.washington.edu <javascript:;>>
> --
> http://mail.python.org/mailman/listinfo/python-list
>


-- 
Cheers,
Chris
--
http://rebertia.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20121013/6303418d/attachment.html>


More information about the Python-list mailing list