如何强制更新其他堆栈框架的Python locals()字典? [英] How can I force update the Python locals() dictionary of a different stack frame?

查看:144
本文介绍了如何强制更新其他堆栈框架的Python locals()字典?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python 2(不确定3)中,仅当您实际调用locals()时才会更新locals字典.例如

In Python 2 (not sure about 3), the locals dictionary only gets updated when you actually call locals(). So e.g.

l=locals()
x=2
l['x']

失败是因为 l 中没有键"x",但是

fails because l doesn't have the key "x" in it, but

l=locals()
x=2
locals()
l['x']

返回2.

我正在寻找一种强制更新 locals 字典的方法,但诀窍是我在不同的堆栈框架中.所以我想做

I'm looking for a way to force an update of the locals dictionary, but the trick is that I'm in a different stack frame. So e.g. I'm looking to do

l=locals()
x=2
force_update()
l['x']

,我需要编写 force_update()函数.我知道从上述函数中,我可以通过 inspect.currentframe().f_back 获得父框架,甚至可以通过 inspect.currentframe().f_back获得父(未更新的)本地人.f_locals ,但是如何强制更新?

and I need to write the force_update() function. I know that from said function I can get the parent frame via inspect.currentframe().f_back, and even the parent (non-updated) locals via inspect.currentframe().f_back.f_locals, but how can I force an update?

如果这看起来有些令人费解,我的主要目标是编写一个表示"{some} string"的简写的函数.format(** dict(globals(),** locals())),所以我不必每次都输入,而可以执行 fmt("{some} string").这样做我遇到了上面的问题.

If this seems convoluted, my main goal is to write a function which is shorthand for "{some} string".format(**dict(globals(),**locals())) so I don't have to type that out each time, and can instead do fmt("{some} string"). Doing so I run into the issue above.

编辑:使用下面的Martjin答案,以下本质上是我正在寻找的解决方案.一个人可以确切地了解他们如何获得被调用者的堆栈框架,这里我通过 partial 来实现.

Edit: With Martjin answer below, below is essentially the solution I was looking for. One could play around with exactly how they get the stack frame of the callee, here I do it via 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 就足够了.

请参见 frame_getlocals() frameobject.c 实现中的code>函数:

See the frame_getlocals() function in the frameobject.c implementation:

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 定义.

PyFrame_FastToLocals is the function used to copy the data from the interal array tracking locals values to a dictionary. frame_getlocals is used to implement the frame.f_locals descriptor (a property); see the frame_getsetlist definition.

上面使用的 PyFrame_FastToLocalsWithError 函数正是 locals()用于生成相同字典的方式(通过

The PyFrame_FastToLocalsWithError function used above is exactly what locals() uses to produce the same dictionary (by wrapping the PyEval_GetLocals function).

这篇关于如何强制更新其他堆栈框架的Python locals()字典?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆