【发布时间】:2018-11-25 13:46:48
【问题描述】:
在 Python 中,函数可以访问封闭范围内的变量。
作为对此范围/一致性的测试,我做了一个创建简单命名空间的实验,但没有得到预期的行为。我不明白为什么要区别对待这种简单的情况,有好的解释吗?
这是一个简单的例子:
import types
bunch = types.SimpleNamespace(
x = 5,
y = 12,
printx = lambda: print(x)
)
在运行上述代码后执行 bundle.printx() 将导致 NameError 因为 x 未定义。但是我们已经定义了一个被包命名空间包围的函数“printx”,但是该函数没有访问封闭命名空间中的变量的权限。
相比之下,将代码 bundle.py 作为外部文件导入会将对象放置在 bundle 命名空间中,并且可以按预期访问封闭命名空间中的变量:
bunch.py:
x = 5,
y = 12,
printx = lambda: print(x)
运行以下代码将按预期打印 5:
import bunch
bunch.printx()
我确实找到了这个问题,可能与此有关:Python: Access from within a lambda a name that's in the scope but not in the namespace 我在此处提供的示例更清楚地特定于访问封闭范围内的变量。
【问题讨论】:
-
您的
lambda的封闭上下文是整个模块;它当然没有包含在bunch命名空间中,因为它甚至还不存在(而且它也不是一个语法结构,所以它实际上不能“包含”任何东西)。 -
@jasonharper 但是当我导入该模块时,它确实被加载到了束命名空间中。但在第一种情况下,我显式地创建了命名空间。具体来说,我很困惑为什么第一种情况无法访问封闭命名空间中的变量,你明白为什么吗?
-
lambda 不知道也不知道关于尚不存在的命名空间的任何信息。函数的封闭范围是一个静态属性,完全在编译时确定。
-
知道了,谢谢。
标签: python