Closure/binding problem or misunderstanding

Boris Borcic bborcic at gmail.com
Fri Nov 9 09:54:37 EST 2007


Bob.Sidebotham at gmail.com wrote:
> If I run the following code:
> 
> class path(object):
>     def __init__(self, **subdirs):
>         for name, path in subdirs.iteritems():
>             def getpath():
>                 return path
>             setattr(self, name, getpath)
> 
> export = path(
>     one = 'this is one',
>     two = 'this is two',
> )
> 
> print "invoking", export.one, export.one()
> print "invoking", export.two, export.two()
> 
> I get this output:
> 
> invoking <function getpath at 0x400ded14> this is one
> invoking <function getpath at 0x400ded84> this is one
> 
> So there apparently are two definitions of the function "getpath" (the
> addresses are different, anyway), but they seem to have the same value
> for the binding of "path". It's not clear to me, after reading what I
> can find about python name binding, whether this is the expected
> behavior, or not (although I was surprised).
> 
> Can anyone enlighten me?

Yes this is the expected behavior. Both your getpath() functions return the 
current value of the single path variable at the time of invocation. Perhaps 
this would be the slightest bit clearer if subdir.iteritems() did not provide 
your items in swapped order (so that the returned values would be "this is two").

To create distinct bindings to distinct values of path at the distinct 
executions of "def getpath() :...", you should write
"def getpath(path=path) :..."

HTH, BB

> 
> Thanks,
> Bob Sidebotham
> 



More information about the Python-list mailing list