471,316 Members | 1,529 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,316 software developers and data experts.

Closure/binding problem or misunderstanding

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 0x400ded14this is one
invoking <function getpath at 0x400ded84this 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?

Thanks,
Bob Sidebotham

Nov 9 '07 #1
2 1119
On Nov 9, 2:32 pm, "Bob.Sidebot...@gmail.com"
<Bob.Sidebot...@gmail.comwrote:
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 0x400ded14this is one
invoking <function getpath at 0x400ded84this 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

Nov 9 '07 #2
On Nov 9, 9:49 am, Paul Hankin <paul.han...@gmail.comwrote:
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)
Thanks, Paul. That's helpful. I will re-read the reference manual, and
see if I can find out where this behavior is defined. It looks like
it's binding both locals and globals, but not actually taking a
snapshot in time, as would, say Perl (I think). From an efficiency POV
this makes great sense, and I can see that you get everything you need
by essentially creating the closure yourself (by putting everything in
the local space for the function).

Bob

Nov 9 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

27 posts views Thread by Ted Lilley | last post: by
9 posts views Thread by Mikito Harakiri | last post: by
4 posts views Thread by Chris | last post: by
19 posts views Thread by Larry Lard | last post: by
7 posts views Thread by Csaba Gabor | last post: by
9 posts views Thread by User1014 | last post: by
reply views Thread by Gerard Brunick | last post: by
11 posts views Thread by Huayang Xia | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.