以下代码只是将lambda放在字典中,并选择lambda给定传递给类构造函数的键。选定的lambda存储为属性。
捕获的是,然后将该选择类的对象设置为模块。
import sys
import logging
LAMBDAS = dict(foo=lambda x: logging.info('foo called with %d', x))
class SelectLambda(object):
def __init__(self, which):
self.selected_lambda = LAMBDAS[which]
sys.modules[__name__] = SelectLambda('foo')
在Python控制台中,运行以下命令(假设上面的代码位于 scope.py 中):
>>> import scope
>>> scope.selected_lambda(15)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "scope.py", line 8, in <lambda>
LAMBDAS = dict(foo=lambda x: logging.info('foo called with %d', x), bar=do_bar)
AttributeError: 'NoneType' object has no attribute 'info'
显然logging.info()
通常存在,并且我已经确认函数中通常通过闭包范围拉入的任何内容都变为None
。
如果用完全成熟的函数引用替换lambda,也会发生这种情况。
应该注意的是,如果没有最后一行sys.modules
修改,这不是问题。
不管最后一行是不是坏习惯,为什么在以这种方式重新定义模块时,闭包信息会被完全丢弃?