当前位置: 首页 > wzjs >正文

企业公司网站制作建设模板网站建站哪家好

企业公司网站制作建设,模板网站建站哪家好,网上购物商城开题报告,网站开发东莞在python3相对导入机制分析的基础上,再分析一下相对导入发生错误的原因,还是以上篇文章中的例子为例,如下所示: 从顶层目录执行相对导入时会报错ImportError: attempted relative import with no known parent package&#xff0…

在python3相对导入机制分析的基础上,再分析一下相对导入发生错误的原因,还是以上篇文章中的例子为例,如下所示:
relative_import
从顶层目录执行相对导入时会报错ImportError: attempted relative import with no known parent package,从下层目录执行相对顶层目录的相对导入时报错ImportError: attempted relative import beyond top-level package,将import_entry.py中的内容改成from . import adv_obj,反编译得到如下字节码:

  0           RESUME                   01           LOAD_CONST               0 (1)LOAD_CONST               1 (('adv_obj',))IMPORT_NAME              0IMPORT_FROM              1 (adv_obj)STORE_NAME               1 (adv_obj)POP_TOPRETURN_CONST             2 (None)

IMPORT_NAME指令和导入普通模块没什么区别,oparg都是0,但是查看import_entry.py的符号表co_names却发现,排在符号表第0位的是个空字符串,进入导入流程PyImport_ImportModuleLevelObject函数中,参数name为空字符串,fromlist为(‘adv_obj’,),level为1,程序流程会进入resolve_name函数中,它的源码如下:

static PyObject *
resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level)
{PyObject *abs_name;PyObject *package = NULL;PyObject *spec = NULL;Py_ssize_t last_dot;PyObject *base;int level_up;if (globals == NULL) {_PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals");goto error;}if (!PyDict_Check(globals)) {_PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict");goto error;}if (PyDict_GetItemRef(globals, &_Py_ID(__package__), &package) < 0) {goto error;}if (package == Py_None) {Py_DECREF(package);package = NULL;}if (PyDict_GetItemRef(globals, &_Py_ID(__spec__), &spec) < 0) {goto error;}if (package != NULL) {if (!PyUnicode_Check(package)) {_PyErr_SetString(tstate, PyExc_TypeError,"package must be a string");goto error;}else if (spec != NULL && spec != Py_None) {int equal;PyObject *parent = PyObject_GetAttr(spec, &_Py_ID(parent));if (parent == NULL) {goto error;}equal = PyObject_RichCompareBool(package, parent, Py_EQ);Py_DECREF(parent);if (equal < 0) {goto error;}else if (equal == 0) {if (PyErr_WarnEx(PyExc_DeprecationWarning,"__package__ != __spec__.parent", 1) < 0) {goto error;}}}}else if (spec != NULL && spec != Py_None) {package = PyObject_GetAttr(spec, &_Py_ID(parent));if (package == NULL) {goto error;}else if (!PyUnicode_Check(package)) {_PyErr_SetString(tstate, PyExc_TypeError,"__spec__.parent must be a string");goto error;}}else {if (PyErr_WarnEx(PyExc_ImportWarning,"can't resolve package from __spec__ or __package__, ""falling back on __name__ and __path__", 1) < 0) {goto error;}if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &package) < 0) {goto error;}if (package == NULL) {_PyErr_SetString(tstate, PyExc_KeyError,"'__name__' not in globals");goto error;}if (!PyUnicode_Check(package)) {_PyErr_SetString(tstate, PyExc_TypeError,"__name__ must be a string");goto error;}int haspath = PyDict_Contains(globals, &_Py_ID(__path__));if (haspath < 0) {goto error;}if (!haspath) {Py_ssize_t dot;dot = PyUnicode_FindChar(package, '.',0, PyUnicode_GET_LENGTH(package), -1);if (dot == -2) {goto error;}else if (dot == -1) {goto no_parent_error;}PyObject *substr = PyUnicode_Substring(package, 0, dot);if (substr == NULL) {goto error;}Py_SETREF(package, substr);}}last_dot = PyUnicode_GET_LENGTH(package);if (last_dot == 0) {goto no_parent_error;}for (level_up = 1; level_up < level; level_up += 1) {last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1);if (last_dot == -2) {goto error;}else if (last_dot == -1) {_PyErr_SetString(tstate, PyExc_ImportError,"attempted relative import beyond top-level ""package");goto error;}}Py_XDECREF(spec);base = PyUnicode_Substring(package, 0, last_dot);Py_DECREF(package);if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) {return base;}abs_name = PyUnicode_FromFormat("%U.%U", base, name);Py_DECREF(base);return abs_name;no_parent_error:_PyErr_SetString(tstate, PyExc_ImportError,"attempted relative import ""with no known parent package");error:Py_XDECREF(spec);Py_XDECREF(package);return NULL;
}

因为当前处于顶层代码执行环境中,所以globals为__main__模块的dict,关于顶层代码执行环境在python标准库__main__的文档中有详细描述,用户指定的第一个执行的python模块即为顶层代码,所以在其中可以使用__name__ == '__main__'这样的形式判断是否处于顶层代码执行环境中。

在虚拟机初始化流程中(pyinit_main->init_interp_main->add_main_module)会创建__main__模块,__main__模块的__package____spec__都为空,也不包含__path__属性,所以程序流程进入内层if语句块中,判断名称中是否包含.号,__main__模块的__name__当然不包含点号,dot为-1,程序跳转到no_parent_error标签处,于是就看到了最终报出的错误attempted relative import with no known parent package。程序返回IMPORT_NAME指令中,检测到返回值为NULL,进入异常处理流程,将该报错打印出来。

再作一个试验,将out_a.py的内容改为from .. import adv_obj,反编译得到字节码如下:

  0           RESUME                   02           LOAD_CONST               0 (2)LOAD_CONST               1 (('adv_obj',))IMPORT_NAME              0IMPORT_FROM              1 (adv_obj)STORE_NAME               1 (adv_obj)POP_TOPRETURN_CONST             2 (None)

与上面的字节码几乎是一样的,唯一不同的是这里的level变成了2,如果将out_a.py作为顶层代码执行的话依然会得到no known parent package错误,执行路径和上面是一样的,因为name依然为空字符串。但是这次不将out_a.py作为顶层代码,而是从import_entry.py进入,通过导入out_a.py模块触发out_a中的导入,这样的话out_a模块相当于处于packageout包中。

在进入out_a模块后已经进入了packageout包的执行环境,在resolve_name中会进入package != NULL分支中进行判断,然后spec也不为NULL,继续进入内层分支,在其中会进行spec.parent是否等于module.__package__的判断,根据对相对导入过程的分析,module.__package__其实就是用spec.parent赋值的,所以正常情况下它们是相等的。

函数继续执行,进入最后的for循环中进行导入层级的判断,代码如下:

......
last_dot = PyUnicode_GET_LENGTH(package);if (last_dot == 0) {goto no_parent_error;}for (level_up = 1; level_up < level; level_up += 1) {last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1);if (last_dot == -2) {goto error;}else if (last_dot == -1) {_PyErr_SetString(tstate, PyExc_ImportError,"attempted relative import beyond top-level ""package");goto error;}}
......

由于这里的level为2,所以会进入for循环中,每一次循环尝试寻找package中的.号,其实就是与level的层级进行匹配,但是这里的package只有一层packageout,所以找不到.号,last_dot为-1,所以就报出了我们看到的错误attempted relative import beyond top-level package,如果resolve_name校验成功,才会进入下面真正导入模块的流程。

通过对以上两种导入错误的分析,可以总结出相对导入的规则,那就是相对导入发生的位置及相对导入的范围不能为顶层代码执行环境,也就是说不能在顶层代码中使用相对导入,也不能导入顶层代码同层级的模块,相对导入只能发生在不含顶层代码层级的package范围内

http://www.dtcms.com/wzjs/167012.html

相关文章:

  • react 做网站杭州网站建设
  • 深圳天琥室内设计学校外贸seo软文发布平台
  • 做网站需要多少资金seo需要培训才能找到工作吗
  • 定制开发响应式网站郑州网站优化哪家好
  • 服饰网站建设 e-idea想学销售去哪培训
  • 网站建设分几步国家大事新闻近三天
  • 猪八戒网网站建设市场推广方案范文
  • 保洁产品网站建设价格营销培训
  • 企业网站开发多少钱企业管理培训课程
  • 环保科技东莞网站建设关键信息基础设施安全保护条例
  • 网站建设优化安徽新乡搜索引擎优化
  • 站长统计幸福宝网站统计百度客服怎么转人工电话
  • 多多卡起货网站建设网站制作需要多少钱
  • 株洲专业建设网站广州seo教程
  • 海南住房和城乡建设委员会门户网站跨境电商平台
  • 2017政府网站建设工作总结seo入门教学
  • wordpress为什么流行网站优化推广
  • 做进口葡萄酒的网站搜索引擎的关键词优化
  • 网上做网站推广骗局seo网站优化做什么
  • 买香港空间上传美女图片做网站今日国内最新新闻
  • 上海html5网站制作公司怎么卸载windows优化大师
  • 网站建设与网页设计总结徐州新站百度快照优化
  • 公司网站更换域名流程建站之星官网
  • 律师论坛网站模板seo推广编辑
  • 众鱼深圳网站建设河北网站推广公司
  • 组织建设六个方面内容广州:推动优化防控措施落
  • 网站开发需求表网络销售都是诈骗公司吗
  • 做一个网站 如何盈利模式百度热搜广告位多少钱
  • 微信公众平台一定要找网站做吗谷歌搜索引擎入口手机版
  • 科技网站推荐域名注册网站查询