Function returns a function

J

James Stroud

Hello,

I want a "function factory" function in python. To do this I made a class like
such (this is for Tkinter, in case your wondering):

class FunctionMaker:
def __init__(self, avar, function, label)
self.var = avar
self.function = function
self.label = label
def __call__(self, e=None):
self.avar.set(self.label)
self.function()

It seems that it would make more sense to make this a function and add it to
the mixin I am writing. But I'm not quite sure how to do this without making
lambdas, which seem a little messy and also look to be on the brink of
deprecation (really not trying to start a lambda pro/con thread here).

Any ideas on how to do this with a regular function, or is the way I've done
it the pythonic choice?

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
P

Paul Rubin

James Stroud said:
Any ideas on how to do this with a regular function, or is the way I've done
it the pythonic choice?

I think you're trying to do something like this:

def FunctionMaker(avar, func, label):
def callback():
avar.set(label)
func()
return callback
 
J

James Stroud

Thank you Paul, this makes much more sense.

James

    def FunctionMaker(avar, func, label):
       def callback():
          avar.set(label)
          func()
       return callback

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
G

Gregory Bond

Paul said:
def FunctionMaker(avar, func, label):
def callback():
avar.set(label)
func()
return callback

I've seen this idiom a lot and I know _what_ it does..... but I can't
work _how_ it does it. How does the name binding work so that "avar" in
the returned function still references the object passed into the
(long-distant!) FunctionMaker() call?

Web pages / turotial ptrs etc gladly accepted.
 
A

Aldo Cortesi

Thus spake Gregory Bond ([email protected]):
I've seen this idiom a lot and I know _what_ it does.....
but I can't
work _how_ it does it. How does the name binding work so
that "avar" in
the returned function still references the object passed
into the
(long-distant!) FunctionMaker() call?

Web pages / turotial ptrs etc gladly accepted.

The lexical scope within which a function is declared is
made available to the function when it is run. This is done
by storing the values of free variables within the declared
function in the func_closure attribute of the created
function object.

If you want to read more, the keyword you're looking for is
"closure" - a quick search on Google for "python closure"
should satisfy your curiosity handily. There is also a neat
recipe for inspecting the values kept in the func_closure
attribute of function objects directly:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/439096






Cheers,


Aldo



--
Aldo Cortesi
(e-mail address removed)
http://www.nullcube.com
Off: (02) 9283 1131
Mob: 0419 492 863
 
P

Paul Rubin

Aldo Cortesi said:
The lexical scope within which a function is declared is
made available to the function when it is run. This is done
by storing the values of free variables within the declared
function in the func_closure attribute of the created
function object.

Actually not quite right:

a = []
for i in range(5):
a.append(lambda: i) # i is free in the lambda
print [f() for f in a]

prints [4,4,4,4,4] instead of [0,1,2,3,4]. The value of i has not
been copied into the closure. Rather, the closure has a cell bound to
the same place that i is bound. So:

for i in range(5):
def f():
j = i # bind a new variable "j" and assign the value from i
return lambda: j # j is free and its value doesn't change
a.append(f())
print [f() for f in a]

prints [0,1,2,3,4]. There's a Pythonic idiom using default args:

a = []
for i in range(5):
a.append(lambda i=i: i) # the "inner" i is free in the lambda
print [f() for f in a]

Closures like may look a little surprising in Python but they're a
standard technique in Scheme. The classic textbook "Structure and
Interpretation of Computer Programming" explains it all. Full text is
online at:

http://mitpress.mit.edu/sicp/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,271
Latest member
BuyAtenaLabsCBD

Latest Threads

Top