Closure/binding problem or misunderstanding

Paul Hankin paul.hankin at gmail.com
Fri Nov 9 09:49:02 EST 2007


On Nov 9, 2:32 pm, "Bob.Sidebot... at gmail.com"
<Bob.Sidebot... 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).

Clearly it wasn't the expected behaviour, or you wouldn't be
surprised :)

It's behaving as defined though, and the usual work-around is to add a
variable with a default value.

class path(object):
    def __init__(self, **subdirs):
        for name, path in subdirs.iteritems():
            def getpath(path=path):
                return path
            setattr(self, name, getpath)

--
Paul Hankin




More information about the Python-list mailing list