簡體   English   中英

urllib3中的相對導入

[英]Relative import in urllib3

我正在研究python如何加載模塊。

我從加載urllib3 requests開始。

我找到了這些行

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.sixurllib3.packages不會加載該文件。

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模塊文件的six.py操作使該模塊添加sys.modules['urllib3.packages.six.moves']以及對標准庫模塊的進一步引用。

Python的導入機制非常復雜。 Python參考文檔在Import系統中對此進行了全面介紹; 要查找的特定條目是:

直接調用__import__()僅執行模塊搜索,如果找到,則執行模塊創建操作。 雖然可能會發生某些副作用, 例如,導入父包以及更新各種緩存(包括sys.modules),但只有import語句執行名稱綁定操作。

並在常規套餐下

導入parent.one將隱式執行parent/__init__.pyparent/one/__init__.py. 隨后導入parent.twoparent.three將分別執行parent/two/__init__.pyparent/three/__init__.py

並在模塊緩存下

導入搜索期間檢查的第一位是sys.modules 該映射充當先前已導入的所有模塊( 包括中間路徑)的緩存。 因此,如果先前導入了foo.bar.baz ,則sys.modules將包含foofoo.barfoo.bar.baz條目。 每個鍵都有對應的模塊對象作為其值。

(在我添加的引用部分中大膽強調)。

請注意, urllib3/packages目錄中的所有內容都是供應商提供的軟件包。 一個通常可以獨立安裝的項目,但urllib3項目已決定將其與自己的發行版打包在一起,從而不必擔心要支持哪些版本。 six是這樣一個獨立的項目,您可以從PyPI安裝它。

您可以在six項目文檔中找到有關six.moves虛擬包的更多信息。 目的是使庫開發人員可以更輕松地編寫與Python 2和Python 3兼容的代碼,而不必擔心在任何一個版本上導入哪個標准庫名稱。

關於Python中的導入功能的一件值得注意的事情是,它不僅可以導入模塊本身,還可以從模塊內部導入變量,類,函數(通常是名稱空間)。 在示例中,您提供了:

from .packages.six.moves.http_client import (
  IncompleteRead as httplib_IncompleteRead
)

import語句引用src/urllib3/packages/six.py模塊中的moves變量,該變量在該文件的第316行定義,並分配給_MovedItems類的實例:

moves = _MovedItems(__name__ + ".moves")

並且http_client是此類實例的屬性或方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM