首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >urllib3中的相对进口

urllib3中的相对进口
EN

Stack Overflow用户
提问于 2018-10-18 20:13:31
回答 2查看 1K关注 0票数 2

我正在研究python是如何加载模块的。

我从加载urllib3requests开始。

我找到了那条线

代码语言:javascript
复制
from .packages.six.moves.http_client import (
  IncompleteRead as httplib_IncompleteRead
)

在称为src/urllib3/exceptions.py的文件中

该导入是相对的,所以我正在查找文件夹src/urllib3/packages/six/moves/http_client.pysrc/urllib3/packages/six/moves/http_client/__init__.py

那些文件根本不存在。

幸运的是,src/urllib3/packages/six.py定义了一个新的模块加载器,因此导入.packages.six.moves.http_client需要http_client核心python模块。

但我不明白src/urllib3/packages/six.py是如何加载的。我还没找到那种进口。

有办法知道哪个模块直接加载src/urllib3/packages/six.py吗?

我尝试过使用__name__全局变量(如建议的这里 )。它的值是urllib3.packages.six,但urllib3.packages不加载该文件。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-18 20:25:31

from .packages.six.moves.http_client import ...表达式导致首先加载.packages.six。Python总是将嵌套包引用中的所有包加载到模块中。

因此,.packages.six.moves.http_client导致Python首先查找urllib3.packages,然后查找urllib3.packages.six,等等。导入机器是通过在sys.modules中查找全名来做到这一点的,如果不存在,则触发每个模块的搜索和加载。

第一次发生这种情况时,sys.modules['urllib3.packages.six']还不存在,导入机器会找到文件urllib3/packages/six.py,在查找更多名称之前导入该文件。

而且,正如您所发现的,导入six.py模块文件的行为会导致该模块添加sys.modules['urllib3.packages.six.moves']并进一步引用标准库模块。

Python的导入机制非常复杂;Python参考文档在https://docs.python.org/3/reference/import.html#regular-packages中全面介绍了这一点;要查找的具体条目如下:

__import__()的直接调用只执行模块搜索,如果找到,则执行模块创建操作。虽然可能会发生某些副作用,但(例如导入父包)和更新各种缓存(包括sys.modules)时,只有导入语句执行名称绑定操作。

以及在https://docs.python.org/3/reference/import.html#regular-packages

导入parent.one将隐式执行parent/__init__.pyparent/one/__init__.py.,随后的parent.twoparent.three导入将分别执行parent/two/__init__.pyparent/three/__init__.py

以及在https://docs.python.org/3/reference/import.html#the-module-cache

在导入搜索期间检查的第一个位置是sys.modules。此映射用作以前导入的所有模块(包括中间路径)的缓存。因此,如果以前导入了foo.bar.bazsys.modules将包含foofoo.barfoo.bar.baz的条目。每个键都将有相应的模块对象作为其值。

(我所加的引文部分以粗体强调)。

请注意,urllib3/packages目录中的所有内容都是一个供应商化的包;这个项目通常是独立安装的,但是urllib3项目已经决定将其打包到自己的发行版中,以避免担心要支持哪个版本。six是一个如此独立的项目,您可以安装它来自PyPI

您可以在虚拟包中找到关于项目文件的更多信息。它的目的是使库开发人员能够更容易地编写与Python 2和Python 3兼容的代码,而不必担心在这两个版本上导入什么标准库名称。

票数 3
EN

Stack Overflow用户

发布于 2018-10-18 20:34:59

Python中导入函数的一个值得注意的地方是,它不仅可以导入模块本身,还可以从模块内部导入变量、类、函数(通常是名称空间)。在本例中,您提供了:

代码语言:javascript
复制
from .packages.six.moves.http_client import (
  IncompleteRead as httplib_IncompleteRead
)

导入语句是指变量从src/urllib3/packages/six.py模块中移出,该模块定义在该文件的第316行,并分配给类_MovedItems的实例。

代码语言:javascript
复制
moves = _MovedItems(__name__ + ".moves")

http_client是该类实例的属性或方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52881839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档