Reading a parent's scope in python
假设我有一个函数层次结构,我希望能够访问(而不是更改!)父级范围。下面是一个示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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的范围吗?
- 这里有示例代码。你可以试试看。
- 我认为这对您来说很有趣:ynniv.com/blog/2007/08/closures-in-python.html
- @Arxanas我所用的示例代码并没有做到这一点,但是它确实说明了问题,请参见第10行。
- 注意,f()的局部变量也包括函数g。
一般来说,不能用Python。如果您的python实现支持堆栈帧(cpython支持),那么您可以使用inspect模块检查调用函数的帧,并提取局部变量,但我怀疑这是解决您想要解决的问题(无论是什么问题)的最佳解决方案。如果你认为你需要的话,你的设计可能有一些缺陷。
请注意,使用inspect将使您能够在调用堆栈中上升,而不是在词汇范围的堆栈中上升。如果从f()返回g,f的范围将消失,因此根本无法访问它,因为它甚至不存在。
- 这是安全的原因,不能这样做吗?我觉得范围是如此微妙/令人困惑,但是一旦你从f内部调用g的话,f的范围肯定仍然"存在",就像后来你回到执行f的时候一样。我之所以想到这是因为单元测试的副作用…的S
- @海登:不,这不是出于安全考虑。如我所说,如果您的python实现支持堆栈帧,那么您可以向上调用堆栈——只需执行类似于inspect.currentframe().f_back.f_locals的操作来获取调用帧的局部变量,这将是您的示例中f的一个实例。您不能从词汇范围访问变量的原因是这个概念不能产生意义。调用堆栈中可以有多个f实例,所有实例都有不同的局部变量,或者根本没有。
- 您不应该这样做的原因是违背了编程语言的要点,它的词法作用域是动态作用域(实际上是任何编程语言)。请参阅en.wikipedia.org/wiki/…,了解更多详细信息。
- 我想让我困惑的是,g确实可以访问f的变量(例如……但我们无法显示它们。
- @Hayden:g()没有访问f的b的权限,除非使用堆栈帧介绍部分,因为它被g的b隐藏。一旦你真正关闭了f的一些名称,它们就会被附加到闭包中,这样你就可以通过内省来访问它们。但是您的代码实际上并不访问f中的任何名称,因此它不会产生一个闭包。
- 啊哈!这就是我所缺少的那一点(它们只有在被人仰视之后才会被依恋)。如果我们可以迭代所有的"可能"变量,我们就完成了……但我们不知道它们是什么!:(
- 如果在函数f中定义f_local_state = locals().keys(),那么在g中,可以迭代f的作用域,因为可以在g中访问f_local_state。