是否可以访问封闭的上下文管理器?

是否可以访问封闭的上下文管理器?,第1张

是否可以访问封闭的上下文管理器?

不幸的是,正如评论中所讨论的,这并非在所有情况下都是可行的。创建上下文管理器后,将运行以下代码(至少在cPython
2.7中运行。我无法评论其他实现):

    case SETUP_WITH:    {        static PyObject *exit, *enter;        w = TOP();        x = special_lookup(w, "__exit__", &exit);        if (!x) break;        SET_TOP(x);            }

__exit__
方法与
SET_TOP
宏一起被压入堆栈,该宏定义为:

#define SET_TOP(v)        (stack_pointer[-1] = (v))

依次将堆栈指针设置为帧eval开始时帧值堆栈的顶部:

stack_pointer = f->f_stacktop;

其中f是frameobject.h中定义的框架对象。对于我们来说不幸的是,这就是小路的终点。只能通过以下方法定义python可访问框架对象:

static PyMemberDef frame_memberlist[] = {    {"f_back",          T_OBJECT,       OFF(f_back),    RO},    {"f_pre",          T_OBJECT,       OFF(f_pre),    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},    {NULL}      };

不幸的是,其中不包括

f_valuestack
我们需要的东西。这是有道理的,因为
f_valuestack
它的类型是
PyObject**
,因此需要将其包装在一个对象中,以便可以以任何方式从python访问。

TL; DR:

__exit__
我们要寻找的方法仅位于一个位置,即框架对象的值堆栈,而cPython并未使python代码可以访问该值堆栈。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5106127.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-17
下一篇2022-11-17

发表评论

登录后才能评论

评论列表(0条)

    保存