这个问题的答案,在解释器中有一些脚手架来检查框架对象,可以通过它来检索sys._getframe()
.框架对象看起来是只读的,但我在文档中找不到任何明显说明这一点的东西.有人可以确认这些对象是可写的(以某种方式)还是只读的?
import sys def foobar(): xx='foo' ff = sys._getframe() ff.f_locals['xx'] = 'bar' print xx if __name__ == '__main__': foobar()
这foo
会在运行时输出' ',但下面的帖子演示了从交互式shell中的当前帧运行时变量是否可写.
从CPython源代码Objects/frameobject.c
:
static PyMemberDef frame_memberlist[] = {
{"f_back", T_OBJECT, OFF(f_back), RO},
{"f_code", T_OBJECT, OFF(f_code), RO},
{"f_builtins", T_OBJECT, OFF(f_builtins),RO},
{"f_globals", T_OBJECT, OFF(f_globals), RO},
{"f_lasti", T_INT, OFF(f_lasti), RO},
{"f_exc_type", T_OBJECT, OFF(f_exc_type)},
{"f_exc_value", T_OBJECT, OFF(f_exc_value)},
{"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)},
{NULL} /* Sentinel */
};
...
static PyGetSetDef frame_getsetlist[] = {
{"f_locals", (getter)frame_getlocals, NULL, NULL},
{"f_lineno", (getter)frame_getlineno,
(setter)frame_setlineno, NULL},
{"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL},
{"f_restricted",(getter)frame_getrestricted,NULL, NULL},
{0}
};
对于PyMemberDef
,标志RO
或READONLY
表示它的属性是只读的.对于PyGetSetDef
,如果它只有一个吸气剂,它是只读的.这就意味着所有的属性,但是f_exc_type
,f_exc_value
,f_exc_traceback
和f_trace
创建后是只读的.在数据模型下的文档中也提到了这一点.
属性引用的对象不一定是只读的.你可以这样做:
>>> f = sys._getframe() >>> f.f_locals['foo'] = 3 >>> foo 3 >>>
虽然这在解释器中起作用,但它在内部函数中失败了.执行引擎为局部变量(f_fastlocals
)使用一个单独的数组,它f_locals
在访问时合并,但反之则不然.
>>> def foo(): ... x = 3 ... f = sys._getframe() ... print f.f_locals['x'] ... x = 4 ... print f.f_locals['x'] ... d = f.f_locals ... x = 5 ... print d['x'] ... f.f_locals ... print d['x'] ... >>> foo() 3 4 4 5 >>>
在全局框架中,f_local
指的是f_globals
,这使得这个技巧在解释器中起作用.修改f_globals
工作,但影响整个模块.