[Python-ideas] For-loop variable scope: simultaneous possession and ingestion of cake
Dillon Collins
dillonco at comcast.net
Tue Oct 14 06:03:03 CEST 2008
On Monday 13 October 2008, Arnaud Delobelle wrote:
> It's inefficient because it works by deconstructing and reconstructing
> the function bytecode.
That's not necessary. Just make a new closure for it. Here's some code (I
was bored/curious). The function reclose_kwds is provided for fun. Enjoy:
def cell(v):
"""Create a cell containing the arg via a dummy function"""
def noop(): return v
return noop.func_closure[0]
def reclose(func, closure):
"""copy func, but use the given closure"""
return function(func.func_code, func.func_globals,
func.func_name, func.func_defaults, closure)
def reclose_kwds(func, **kwds):
"""update func's closure using the names/values given as keywords"""
cinfo = zip(func.func_code.co_freevars, func.func_closure)
closure = tuple(cell(kwds[v]) if v in kwds else c for v,c in cinfo)
return reclose(func, closure)
def close(*names):
"""lock the given (non-global) variable names to their current values for
function"""
def _close(func):
cinfo = zip(func.func_code.co_freevars, func.func_closure)
closure = tuple(cell(c.cell_contents) if v in names else c for v,c in cinfo)
return reclose(func, closure)
return _close
def close_all(func):
"""lock all non-global variables in function to their current values"""
closure = tuple(cell(c.cell_contents) for c in func.func_closure)
return reclose(func, closure)
def g():
j=1
def f():
ret = []
for i in range(3):
#q=lambda x:x*i*j
def q(x): return x*i*j
ret.append(q)
return ret
return f()
def g2():
j=1
def f():
ret = []
for i in range(3):
#q=close('i')(lambda x:x*i*j)
@close('i')
def q(x): return x*i*j
ret.append(q)
return ret
return f()
q1, q2, q3 = g()
p1, p2, p3 = g2()
print q1, q1(2)
print q2, q2(2)
print q3, q3(2)
print
print p1, p1(2)
print p2, p2(2)
print p3, p3(2)
print
More information about the Python-ideas
mailing list