修改locals()或frame.f_locals中的* existing *变量 [英] Modify *existing* variable in `locals()` or `frame.f_locals`

查看:285
本文介绍了修改locals()或frame.f_locals中的* existing *变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一些与此问题相关的模糊问题,但没有找到任何针对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 a locals() like dictionary, but less prone to hackish things through exec. Or at least I have been less able to do hackish undocumented things like the locals()['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 。这是通过 sys.settrace 设置跟踪器的用例。

  • 一个人可以轻松访问其中包含框架的函数-将设置跟踪并将其用于给定触发器或任何其他变量的局部变量进行处理的用例。

  • In a function f, one can access the f.func_code.co_nlocals and f.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 through sys.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 正在执行

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屋!

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