如何强制更新不同堆栈框架的 Python locals() 字典?
How can I force update the Python locals() dictionary of a different stack frame?
在 Python 2(不确定 3)中,locals 字典仅在您实际调用 locals() 时才会更新。所以例如
l=locals()
x=2
l['x']
失败,因为 l
中没有密钥 "x",但是
l=locals()
x=2
locals()
l['x']
returns 2.
我正在寻找一种强制更新本地字典的方法,但诀窍是我在不同的堆栈框架中。所以例如我想做
l=locals()
x=2
force_update()
l['x']
我需要编写 force_update()
函数。我知道从上述函数中我可以通过 inspect.currentframe().f_back
获取父框架,甚至通过 inspect.currentframe().f_back.f_locals
获取父(未更新的)局部变量,但我如何强制更新?
如果这看起来很复杂,我的主要目标是为 "{some} string".format(**dict(globals(),**locals()))
编写一个 shorthand 的函数,这样我就不必每次都输入它,而是可以 fmt("{some} string")
。这样做我 运行 进入了上面的问题。
编辑:下面是 Martjin 的回答,下面基本上是我正在寻找的解决方案。人们可以弄清楚他们是如何获得被调用者的堆栈帧的,这里我通过 partial
来做到这一点。
from functools import partial
from inspect import currentframe
fmt = partial(lambda s,f: s.format(**dict(globals(),**f.f_locals)),f=currentframe())
x=2
print fmt("{x}") #prints "2"
只需访问框架对象f_locals
即可触发复制,因此使用inspect.currentframe().f_back.f_locals
就足够了。
参见frameobject.c
实现中的frame_getlocals()
function:
static PyObject *
frame_getlocals(PyFrameObject *f, void *closure)
{
PyFrame_FastToLocals(f);
Py_INCREF(f->f_locals);
return f->f_locals;
}
PyFrame_FastToLocals
是用于将数据从跟踪本地值的内部数组复制到字典的函数。 frame_getlocals
用于实现frame.f_locals
描述符(一个属性);见 frame_getsetlist
definition.
上面使用的 PyFrame_FastToLocalsWithError
函数 正是 locals()
用来生成相同字典的函数(由 wrapping the PyEval_GetLocals
function)。
在 Python 2(不确定 3)中,locals 字典仅在您实际调用 locals() 时才会更新。所以例如
l=locals()
x=2
l['x']
失败,因为 l
中没有密钥 "x",但是
l=locals()
x=2
locals()
l['x']
returns 2.
我正在寻找一种强制更新本地字典的方法,但诀窍是我在不同的堆栈框架中。所以例如我想做
l=locals()
x=2
force_update()
l['x']
我需要编写 force_update()
函数。我知道从上述函数中我可以通过 inspect.currentframe().f_back
获取父框架,甚至通过 inspect.currentframe().f_back.f_locals
获取父(未更新的)局部变量,但我如何强制更新?
如果这看起来很复杂,我的主要目标是为 "{some} string".format(**dict(globals(),**locals()))
编写一个 shorthand 的函数,这样我就不必每次都输入它,而是可以 fmt("{some} string")
。这样做我 运行 进入了上面的问题。
编辑:下面是 Martjin 的回答,下面基本上是我正在寻找的解决方案。人们可以弄清楚他们是如何获得被调用者的堆栈帧的,这里我通过 partial
来做到这一点。
from functools import partial
from inspect import currentframe
fmt = partial(lambda s,f: s.format(**dict(globals(),**f.f_locals)),f=currentframe())
x=2
print fmt("{x}") #prints "2"
只需访问框架对象f_locals
即可触发复制,因此使用inspect.currentframe().f_back.f_locals
就足够了。
参见frameobject.c
实现中的frame_getlocals()
function:
static PyObject *
frame_getlocals(PyFrameObject *f, void *closure)
{
PyFrame_FastToLocals(f);
Py_INCREF(f->f_locals);
return f->f_locals;
}
PyFrame_FastToLocals
是用于将数据从跟踪本地值的内部数组复制到字典的函数。 frame_getlocals
用于实现frame.f_locals
描述符(一个属性);见 frame_getsetlist
definition.
上面使用的 PyFrame_FastToLocalsWithError
函数 正是 locals()
用来生成相同字典的函数(由 wrapping the PyEval_GetLocals
function)。