阅读家长';python中的s作用域

阅读家长';python中的s作用域,python,scope,local-variables,Python,Scope,Local Variables,假设我有一个函数层次结构,我希望能够访问(而不是更改!)父范围。这里是一个说明性的例子 def f(): a = 2 b = 1 def g(): b = 2 c = 1 print globals() #contains a=1 and d=4 print locals() #contains b=2 and c=1, but no a print dict(globals(), **loc

假设我有一个函数层次结构,我希望能够访问(而不是更改!)父范围。这里是一个说明性的例子

def f():
    a = 2
    b = 1
    def g():
        b = 2
        c = 1
        print globals() #contains a=1 and d=4
        print locals() #contains b=2 and c=1, but no a
        print dict(globals(), **locals()) #contains a=1, d=4 (from the globals), b=2 and c=1 (from g)
        # I want a=2 and b=1 (from f), d=4 (from globals) and no c
    g()
a = 1
d = 4
f()

我可以从
g
中访问
f
的范围吗?

通常,在Python中不能访问。如果Python实现支持堆栈帧(CPython支持),那么可以使用
inspect
模块检查调用函数的帧并提取局部变量,但我怀疑这是否是您想要解决的问题的最佳解决方案(不管是什么)。如果你认为你需要这个,你的设计可能有一些缺陷


请注意,使用
inspect
将使您能够进入调用堆栈,而不是词法作用域堆栈。如果从
f()
返回
g
,则
f
的作用域将消失,因此根本无法访问它,因为它根本不存在。

这里有示例代码。您可以试一试。我想您会感兴趣:@arxanas我的示例代码没有做到这一点,但是它确实说明了问题,请参见第10行。请注意,
f()
的局部变量也包括函数
g
。不能这样做是出于安全原因吗?我发现范围如此微妙/令人困惑,但一旦你从
f
中调用
g
,那么
f
的范围肯定仍然“存在”,因为之后你返回执行
f
(!)我之所以想到这一点是因为s@hayden:不,不是出于安全原因。正如我所说的,如果Python实现支持堆栈帧,您可以向上调用堆栈–只需执行类似于
inspect.currentframe().f_back.f_locals
的操作即可获得调用帧的局部变量,在您的示例中,这将是
f
的一个实例。不能从词法范围访问变量的原因是这个概念没有意义。调用堆栈中可能有多个
f
实例,所有实例都具有不同的局部变量,也可能根本没有。您不应该这样做的原因是违背了将词法作用域设置为动态作用域的编程语言(实际上是任何编程语言)的要点。请参阅以了解更多详细信息。我认为让我困惑的是,
g
确实可以访问
f
的变量()。。。但是我们不能显示它们。@hayden:
g()
无权访问
f
b
,除非您使用堆栈帧插入,因为它被
g
b
隐藏。一旦你真的关闭了
f
的一些名字,它们就会附在关闭上,因此你可以通过内省来访问它们。但是您的代码实际上不从
f
访问任何名称,因此它不会产生闭包。