kaka4NERV
kaka4NERV

Reputation: 23

The purpose of lambda x: lambda: x

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

Answers (1)

user2357112
user2357112

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

Related Questions