Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何强制更新不同堆栈框架的Python locals()字典?_Python_Python Internals_Inspect_Stack Frame_Locals - Fatal编程技术网

如何强制更新不同堆栈框架的Python locals()字典?

如何强制更新不同堆栈框架的Python locals()字典?,python,python-internals,inspect,stack-frame,locals,Python,Python Internals,Inspect,Stack Frame,Locals,在Python 2中(不确定是否为3),只有在实际调用locals()时,才会更新locals字典。例如 失败,因为l中没有键“x”,但是 l=locals() x=2 locals() l['x'] 返回2 我正在寻找一种强制更新本地词典的方法,但诀窍是我处于不同的堆栈框架中。所以,例如,我希望 l=locals() x=2 force_update() l['x'] 我需要编写force\u update()函数。我知道,通过上述函数,我可以通过inspect.currentframe(

在Python 2中(不确定是否为3),只有在实际调用locals()时,才会更新locals字典。例如

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

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

我正在寻找一种强制更新本地词典的方法,但诀窍是我处于不同的堆栈框架中。所以,例如,我希望

l=locals()
x=2
force_update()
l['x']
我需要编写
force\u update()
函数。我知道,通过上述函数,我可以通过
inspect.currentframe().f_back
获取父帧,甚至可以通过
inspect.currentframe().f_back.f_locals
获取父(未更新)局部变量,但我如何强制更新呢

如果这看起来很复杂,我的主要目标是编写一个函数,它是
“{some}string.format(**dict(globals(),**locals())
的缩写,因此我不必每次都键入它,而是可以执行
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_局部变量
即可触发复制,因此使用
inspect.currentframe().f_back.f_局部变量
就足够了

请参见
frameobject.c
实现中的:

静态PyObject*
frame_getlocals(PyFrameObject*f,void*closure)
{
PyFrame_FastToLocals(f);
Py_增量(f->f_局部变量);
返回f->f_局部变量;
}
PyFrame\u FastToLocals
是用于将数据从内部数组跟踪局部值复制到字典的函数
frame\u getlocals
用于实现
frame.f\u locals
描述符(一个属性);看


上面使用的
PyFrame\u FastToLocalsWithError
函数正是
locals()
用来生成同一个字典的函数。

在编辑器中,您可以定义一个快捷方式、代码段或任何编辑器调用的函数,以扩展到
。格式(**dict(globals(),**locals())
。很多编辑器都支持这样的功能。为什么在代码中多次使用
“{some}string.format(**dict(globals(),**locals())
?您的格式字符串真的需要访问本地和全局名称空间中的每个变量吗?如果您可以获得父帧(请参见
sys.\u getframe(1)
),那么为什么需要
globals()
locals()
?啊哈!谢谢我设法找到了
currentframe().f_locals
,但没有意识到它确实会强制我正在寻找的更新。是的-请注意,不会发生相反的情况-无法通过更改局部变量中的值来更新快速变量。@CharlieParker:我在回答中链接到了Python 3源代码;是的,它在Python3中工作。@MartijnPieters等待您是否真的能够更新局部变量并使其工作?我一直在找这样的东西,一点运气都没有。为什么你的方法有效,而其他方法却失败了?@CharlieParker:Python在函数中大量优化了局部名称空间。
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"