Help me dig my way out of nested scoping
Terry Reedy
tjreedy at udel.edu
Sun Apr 3 19:09:32 EDT 2005
"Brendan" <spam4bsimons at yahoo.ca> wrote in message
news:1112562768.181026.180140 at l41g2000cwc.googlegroups.com...
> I have a function, call it F(x), which asks for two
> other functions as arguments, say A(x) and B(x). ...
If I understand this and the rest, a third party library whose code you
cannot modify (easily) has a function F with (at least) three parameters:
A, B, and x. During its operation, F calls A(x) and B(x). Because of code
commonality for the particular A and B arg funcs you want to feed to F, you
want avoid duplication by having the first call to either to calculate both
return values.
If F calls each of A and B exactly once and always in the same order and
only for the value x you supply, the solution is pretty easy. A calls AB,
stashes the B value away where it can be retrieved, and return the A value.
B retrieves the B value and returns it. But your problem is the stash and
retrieve part. Solutions:
1. global variable (easiest) - use global declaration in A;
2. closure variable - use mutable such as 1 element list (see below);
3. instance attribute - with A and B as methods.
2 is what you tried to do, but without knowing the mutable (list or dict)
trick:
def ABwrapper():
bsave = [None]
def A(x):
aval,bval = AB(x)
bsave[0] = bval
return aval
def B(x):
return bsave[0]
return A,B
This works because A does not try to *rebind* bsave to a new object. It
only mutates the existing object.
If the order of calling changes, you need more logic. If F calls A and B
on multiple 'x's, as with, for instance, a derivative approximizer, then I
would memoize A and/or B using the recipe posted here more than once and on
the cookbook site and included in the new Python Cookbook v2 (and maybe v1,
don't have it).
Terry J. Reedy
More information about the Python-list
mailing list