修改locals()或frame.f_locals中的* existing *变量 [英] Modify *existing* variable in `locals()` or `frame.f_locals`
问题描述
我发现了一些与此问题相关的模糊问题,但没有找到任何针对CPython的干净且特定的解决方案。并且我认为有效的解决方案是特定于解释器的。
I have found some vaguely related questions to this question, but not any clean and specific solution for CPython. And I assume that a "valid" solution is interpreter specific.
首先,我认为我了解:
-
locals()
给出了不可修改的字典。 - 一个函数可以(并且确实可以)使用某种优化来访问其局部变量
-
frame.f_locals
给出locals()
类似于字典,但不太容易通过exec
修改内容。或至少我没有能力做些骇人听闻的未记载的事情,例如locals()[’var’] = value; exec
-
exec
能够对局部变量做一些奇怪的事情,但事实并非如此。可靠-例如我在某处读到它在Python 3中不起作用。未经测试。
locals()
gives a non-modifiable dictionary.- A function may (and indeed does) use some kind of optimization to access its local variables
frame.f_locals
gives alocals()
like dictionary, but less prone to hackish things throughexec
. Or at least I have been less able to do hackish undocumented things like thelocals()['var'] = value ; exec ""
exec
is capable to do weird things to the local variables, but it is not reliable --e.g. I read somewhere that it doesn't work in Python 3. Haven't tested.
所以我了解,鉴于这些限制,
但是,应该有可能进行更改,因此将额外的变量添加到本地变量永远是不安全的,因为这会破坏解释器的结构。
So I understand that, given those limitations, it will never be safe to add extra variables to the locals, because it breaks the interpreter structure.
我考虑过的事情
- 在函数
f
中,可以访问f.func_code.co_nlocals
和f。 func_code.co_varnames
。 - 在框架中,可以通过
frame.f_locals $ c访问/检查/读取变量。 $ c>。这是通过
sys.settrace
设置跟踪器的用例。 - 一个人可以轻松访问其中包含框架的函数-将设置跟踪并将其用于给定触发器或任何其他变量的局部变量进行处理的用例。
- In a function
f
, one can access thef.func_code.co_nlocals
andf.func_code.co_varnames
. - In a frame, the variables can be accessed / checked / read through the
frame.f_locals
. This is in the use case of setting a tracer throughsys.settrace
. - One can easily access the function in which a frame is --cosidering the use case of setting a trace and using it to "do things" in with the local variables given a certain trigger or whatever.
变量应该在某个地方,最好是可写的...但是我找不到它。即使它是一个数组(用于解释程序的有效访问),或者我需要一些额外的C特定布线,我都准备好提交给它。
The variables should be somewhere, preferably writeable... but I am not capable of finding it. Even if it is an array (for interpreter efficient access), or I need some extra C-specific wiring, I am ready to commit to it.
如何实现从跟踪函数或从修饰的包装函数或类似的函数中修改变量?
How can I achieve that modification of variables from a tracer function or from a decorated wrapped function or something like that?
当然可以理解完整的解决方案,但即使是某些指针也会对我有帮助很大,因为我在这里用了很多不可写的字典:-/
A full solution will be of course appreciated, but even some pointers will help me greatly, because I'm stuck here with lots of non writeable dictionaries :-/
Hackish exec
is doing things like this or this
推荐答案
存在一个未记录的C-API调用像这样的事情:
It exists an undocumented C-API call for doing things like that:
PyFrame_LocalsToFast
此PyDev bl og post 。基本思想似乎是:
import ctypes
...
frame.f_locals.update({
'a': 'newvalue',
'b': other_local_value,
})
ctypes.pythonapi.PyFrame_LocalsToFast(
ctypes.py_object(frame), ctypes.c_int(0))
我尚未测试它是否按预期工作。
I have yet to test if this works as expected.
请注意,如果要求仅是对现有变量的修改,则可能有某种方法可以直接访问 Fast
,从而避免了间接访问。但是,由于这似乎主要是未记录在案的API,因此源代码是该文档的资源。
Note that there might be some way to access the Fast
directly, to avoid an indirection if the requirements is only modification of existing variable. But, as this seems to be mostly non-documented API, source code is the documentation resource.
这篇关于修改locals()或frame.f_locals中的* existing *变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!