On Mar 1, 8:50 pm, Michael Torrie <[EMAIL PROTECTED]> wrote: > I need to use a lambda expression to bind some extra contextual data > (should be constant after it's computed) to a call to a function. I had > originally thought I could use something like this demo (but useless) code: > > funcs=[] > > def testfunc(a,b): > print "%d, %d" % (a,b) > > for x in xrange(10): > funcs.append(lambda p: testfunc(x+2,p)) > > Now what I'd like is to call, for example, funcs[0](4) and it should > print out "2,4". In other words I'd like the value of x+2 be encoded > into the lambda somehow, for funcs[x]. However the disassembly shows > this, which is reasonable, but not what I need: > > >>> dis.dis(funcs[0]) > > 2 0 LOAD_GLOBAL 0 (testfunc) > 3 LOAD_GLOBAL 1 (x) > 6 LOAD_CONST 0 (2) > 9 BINARY_ADD > 10 LOAD_FAST 0 (p) > 13 CALL_FUNCTION 2 > 16 RETURN_VALUE > > The LOAD_GLOBAL 1 (x) line is definitely a problem. For one it refers > to a variable that won't be in scope, should this lambda be called from > some stack frame not descended from the one where I defined it. > > So how can I create a lambda expression that calculates a constant based > on an expression, rather than referring to the object itself? Can it be > done? > > Michael
I hate that. Especially since ints are immutable. >>> from functools import partial >>> funcs= [ partial( print, x ) for x in range( 10 ) ] >>> for func in funcs: ... func() ... 0 1 2 3 4 5 6 7 8 9 >>> takes advantage of 2.5+ functools.partial and 3.0 print. You can use sys.stdout instead of print in the example in 2.5, but without partial, you're at: class Val: def __init__( self, val ): self.val= val def __call__( self ): self.val+= 10 val= Val( 20 ) val() . There's also a CellMaker implementation somewhere on Py-Ideas, but it was outlawed in 18 provinces, and it just evaluates and compiles a string anyway. for x in xrange(10): fun= exec( 'lambda p: testfunc(%i+2,p)'% x ) funcs.append( fun ) -- http://mail.python.org/mailman/listinfo/python-list