令人惊讶的是,检查 lambda 是否可以在没有关联闭包的情况下工作实际上相当容易。根据数据模型文档 http://docs.python.org/release/2.6.2/reference/datamodel.html,你可以只检查func_closure
属性:
>>> def get_lambdas():
... bar = 42
... return (lambda: 1, lambda: bar)
...
>>> no_vars, vars = get_lambdas()
>>> print no_vars.func_closure
None
>>> print vars.func_closure
(<cell at 0x1020d3d70: int object at 0x7fc150413708>,)
>>> print vars.func_closure[0].cell_contents
42
>>>
然后序列化 + 加载 lambda 就相当简单了:
>>> import marshal, types
>>> old = lambda: 42
>>> old_code_serialized = marshal.dumps(old.func_code)
>>> new_code = marshal.loads(old_code_serialized)
>>> new = types.FunctionType(new_code, globals())
>>> new()
42
值得一看的文档FunctionType
:
function(code, globals[, name[, argdefs[, closure]]])
Create a function object from a code object and a dictionary.
The optional name string overrides the name from the code object.
The optional argdefs tuple specifies the default argument values.
The optional closure tuple supplies the bindings for free variables.
请注意,您还可以提供一个闭包...这意味着您甚至可以序列化旧函数的闭包,然后在另一端加载它:)