python load是什么意思_python字节码中loadname和loadglobal有什么区别?

LOAD_NAME和{}之间的区别在于它们搜索给定的name。在

LOAD_NAME

当Python遇到LOAD_NAME操作码时:它首先在f_locals-当前帧对象的本地名称中搜索。在

如果它在f_locals中找不到给定的名称,那么它将继续在f_globals中搜索框架对象的全局名称。这些是框架对象周围范围内的名称。在

如果在f_globals中找不到该名称,那么它将搜索f_builtins。f_builtins是Python使用的内置名称的字典。在

如果以上所有操作都失败,Python将引发一个NameError。在

这里是虚拟机执行LOAD_NAME指令的相关C代码:TARGET(LOAD_NAME) {

PyObject *name = GETITEM(names, oparg);

PyObject *locals = f->f_locals;

PyObject *v;

if (locals == NULL) {

PyErr_Format(PyExc_SystemError,

"no locals when loading %R", name);

goto error;

}

if (PyDict_CheckExact(locals)) {

v = PyDict_GetItem(locals, name);

Py_XINCREF(v);

}

else {

v = PyObject_GetItem(locals, name);

if (v == NULL) {

if (!PyErr_ExceptionMatches(PyExc_KeyError))

goto error;

PyErr_Clear();

}

}

if (v == NULL) {

v = PyDict_GetItem(f->f_globals, name);

Py_XINCREF(v);

if (v == NULL) {

if (PyDict_CheckExact(f->f_builtins)) {

v = PyDict_GetItem(f->f_builtins, name);

if (v == NULL) {

format_exc_check_arg(

PyExc_NameError,

NAME_ERROR_MSG, name);

goto error;

}

Py_INCREF(v);

}

else {

v = PyObject_GetItem(f->f_builtins, name);

if (v == NULL) {

if (PyErr_ExceptionMatches(PyExc_KeyError))

format_exc_check_arg(

PyExc_NameError,

NAME_ERROR_MSG, name);

goto error;

}

}

}

}

PUSH(v);

DISPATCH();

}

LOAD_GLOBAL

当Python遇到LOAD_GLOBAL操作码时:Python首先在f_globals中搜索名称,即当前帧对象引用的周围范围中的名称。在

如果在f_globals中找不到该名称,那么它将搜索f_builtins。f_builtins是Python使用的内置名称的字典。在

{12>如果上面的所有cda}都失败了。在

这里是虚拟机执行LOAD_GLOBAL指令的相关C代码:

^{pr2}$

那么,有什么区别?在

正如您可能看到的,不同之处在于LOAD_GLOBAL直接跳过搜索框架对象的全局名称,而LOAD_NAME则开始搜索本地名称,并向上搜索。LOAD_GLOBAL操作码对于Python已经知道名称不能是本地名称的情况非常有用,因此它完全跳过了对本地名称的搜索。在

注意:如果您想了解更多关于Python虚拟机如何工作的信息,我将查看Byterun,它是CPython虚拟机的纯Python实现。它也有一个accompanying article由艾莉森·卡普特创作。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值