为什么设置sys.modules [__ name__]会删除闭包范围?

时间:2016-05-12 23:14:07

标签: python closures

以下代码只是将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修改,这不是问题。

不管最后一行是不是坏习惯,为什么在以这种方式重新定义模块时,闭包信息会被完全丢弃?

0 个答案:

没有答案