Reputation: 23
I was reading the code of byterun(a python python interpreter), and I can't understand lines below that something about closure and lambda:
def make_cell(value):
fn = (lambda x: lambda: x)(value)
return fn.__closure__[0]
The function was called in The second to the last line:
class Function(object):
__slots__ = [... omit ...]
def __init__(self, name, code, globs, defaults, closure, vm):
self._vm = vm
self.func_code = code
self.func_name = self.__name__ = name or code.co_name
self.func_defaults = tuple(defaults)
self.func_globals = globs
self.func_locals = self._vm.frame.f_locals
self.__dict__ = {}
self.func_closure = closure
self.__doc__ = code.co_consts[0] if code.co_consts else None
kw = {
'argdefs': self.func_defaults,
}
if closure:
kw['closure'] = tuple(make_cell(0) for _ in closure)
self._func = types.FunctionType(code, globs, **kw)
What's the function's purpose? And how does it work(especially with 2 lambda)?
Upvotes: 2
Views: 508
Reputation: 281262
The purpose of this lambda x: lambda: x
construct is to create a closure cell object, the objects Python uses to implement closure variables. The nested lambda: x
uses the x
variable from the outer lambda
, so Python needs to create a closure cell for the x
variable. Calling the outer lambda:
(lambda x: lambda: x)(value)
creates a function object for the inner lambda
with a closure cell for the x
variable holding value
, and the __closure__
access:
return fn.__closure__[0]
accesses the function object's tuple of closure variables to retrieve and return the closure cell.
Upvotes: 1