2012-02-15 141 views
11

如果我這樣做:爲什麼導入python模塊不導入嵌套模塊?

import lxml 

在Python,lxml.html沒有進口。例如,我不能調用lxml.html.parse()函數。這是爲什麼?

+3

您可能注意到'import os'允許您在代碼中使用'os.path.whatever'。所以,這取決於模塊的作者。 – 2012-02-15 23:34:04

回答

12

導入在Python的模塊或程序包是一個概念上簡單的操作:

  1. 查找對應於所述進口的.py文件。這涉及Python路徑和一些其他機器,但會導致找到特定的.py文件。

  2. 對於導入中的每個目錄級別(import foo.bar.baz有兩個級別),找到相應的__init__.py文件並執行它。執行它只是意味着在文件中運行所有的頂級語句。

  3. 最後,.py文件本身(本例中爲foo/bar/baz.py)被執行,這意味着所有的頂級語句都被執行。所有作爲該執行結果而創建的全局變量都被捆綁到一個模塊對象中,並且該模塊對象是導入的結果。

如果這些步驟都沒有導入子包,那麼這些子包不可用。如果他們確實導入了子包,那麼他們就可以使用。包裝作者可以按照自己的意願去做。

+0

我認爲值得澄清的是,在導入包時,在步驟1中找到的.py文件是該包的\ _ \ _ init \ _ \ _。py。除非在\ _ \ _init \ _ \ _。py文件中導入子包,否則它們將不可用。 – 2017-07-03 06:13:37

1

這是爲了允許只有最少量的代碼必須加載多部分庫,您可能不會使用整個。例如,你可能沒有使用lxmlhtml部分,因此不想處理加載它的代碼。

2

lxml是一個包,而不是一個模塊。包是一組模塊。碰巧,您也可以直接導入包,但不會自動導入其所有子模塊。

至於爲什麼這是好的,這是BDFL的問題。我認爲這可能是因爲軟件包通常很大,導入所有子模塊會導致性能下降。

6

lxml在Python中被稱爲package,它是模塊的分級集合。軟件包可以是巨大的,因此它們可以選擇性地關於它們在導入時被拉入的內容。否則,每個人都必須導入完整的層次結構,這會浪費資源。

4

這是設計。該軟件包可以選擇在其__init__.py中導入嵌套軟件包,然後,您將可以毫無問題地訪問嵌套軟件包。這對於軟件包編寫者來說是一個選擇問題,目的是儘量減少可能不會使用的代碼量。