Python中的絕對匯入和相對匯入

2022-08-10 02:15:21 字數 3273 閱讀 5207

如果你做過有多個檔案的python專案,那麼你一定用過import語句。

即使是對於有多個專案的python支持者來說,import也會讓人困惑!你可能正閱讀本文,因為希望更深入地了解python中的匯入,尤其是絕對和相對匯入。在本教程中,你將了解兩者之間的差異,以及它們的利弊。我們立即開始吧!

你需要對python模組和包有乙個很好的理解,以了解匯入的工作方式。python模組是乙個副檔名是.py的檔案,python包是其中包含模組的任何資料夾(或者,在python 2中,是至少包含乙個__init__.py檔案的資料夾)。

當乙個模組中的**需要訪問另乙個模組或包中的**時,會發生什麼情況?匯入它!

但import究竟是如何工作的呢?假設你匯入乙個模組abc,就像這樣:

python要做的第一件事是查詢sys.modules中的abc名稱。這是預先匯入的所有模組的快取。

如果在模組快取中沒有找到該名稱,python將通過內建模組列表進行搜尋。這些模組是和python一起預先安裝的,並且可以在python標準庫中找到。如果在內建模組中仍沒有找到該名稱,那麼python在sys.path定義的目錄列表中搜尋它。此列表通常包括當前目錄,首先搜尋該目錄。

當python找到該模組時,將它繫結到本地作用域中的名稱。這意味著現在定義了abc,而且可以在當前檔案中使用,而不引發nameerror。

如果找不到該名字,會得到modulenotfounderror。你可以在python文件找到更多關於匯入的資訊!

注意:安全問題

請注意,python的匯入系統會帶來一些重大的安全風險。這主要是由於其靈活性。例如,模組快取是可寫的,並且有可能使用匯入系統重寫python核心功能。從第三方軟體包匯入也可能給應用程式帶來安全威脅。

既然你知道匯入語句是如何工作的,讓我們來**它們的語法。你可以匯入包和模組。(注意,匯入乙個包基本上是匯入包的__init__.py檔案作為模組。)還可以從包或模組中匯入特定的物件。

一般有兩種型別的匯入語法。當使用第一種時,直接匯入資源,如下所示:

abc可以是乙個包或乙個模組。

當使用第二種語法時,從另乙個包或模組匯入資源。下面是乙個例子:

xyz可以是模組、子包或物件,例如類或函式。你還可以重新命名匯入的資源,如:

這在指令碼內將匯入的資源abc重新命名為other_name。它現在必須被引用為other_name,否則它將不被識別。

python的官方風格指南——pep 8,在編寫匯入語句時有幾個忠告。總結如下:

1. 匯入總是位於檔案的頂部,在任何模組注釋和文件字串之後。

2. 匯入應該根據匯入情況來劃分。通常有三類:

3. 每一組匯入應該被空行隔開。

在每個匯入組中按字母順序排列匯入也是乙個好主意。這使得查詢特定的匯入更加容易,尤其是當檔案中有許多匯入時。

下面是如何設計匯入語句的示例:

上面的匯入語句被劃分為三個不同的組,由空行分隔。它們也按字母順序排列在每組中。

假設你有以下目錄結構:

有乙個project目錄,包含兩個子目錄,package1和package2。package1目錄有兩個檔案,module1.py和module2.py。

package2目錄有三個檔案:兩個模組:module3.py和module4.py,以及初始化檔案__init__.py。它還包含乙個目錄subpackage1,subpackage1又包含乙個檔案module5.py。

假設如下:

1.package1/module2.py包含乙個函式function1。

2.package2/__init__.py包含乙個類class1.

3.package2/subpackage1/module5.py包含乙個函式function2.

以下是絕對匯入的實際例子:

請注意,必須從頂級包資料夾中為每個包或檔案提供詳細路徑。這有點類似於它的檔案路徑,但是我們使用點(.)代替斜槓(/)。

絕對匯入是首選,因為它們非常明確和直接。僅僅通過檢視語句就可以很容易地確定匯入資源的位置。此外,即使匯入語句的當前位置發生更改,絕對匯入仍然有效。事實上,pep 8明確建議絕對匯入。

然而,有時,絕對匯入會變得相當冗長,這取決於目錄結構的複雜性。想象一下有這樣的語句:from package1.subpackage2.subpackage3.subpackage4.module5 import function6 那太荒謬了,對吧?幸運的是,在這種情況下,相對匯入是乙個很好的選擇!

相對匯入指定資源相對於當前位置匯入,即匯入語句所在的位置。相對匯入有兩種型別:隱式和顯式。隱式相對匯入在python 3中已經被棄用,所以我不會在這裡涉及它們。

相對匯入的語法取決於當前位置以及要匯入的模組、包或物件的位置。下面是一些相對匯入的例子:

你可以看到上面每個匯入語句中至少有乙個點。相對匯入使用點標記來指定位置。

乙個點意味著引用的模組或包位於與當前位置相同的目錄中。兩個點意味著它在當前位置的父目錄中,也就是上層的目錄。三個點意味著它在祖父母目錄中,等等。如果你使用類似unix的作業系統,可能對此很熟悉!

假設你擁有與以前相同的目錄結構:

回憶檔案內容:

1.package1/module2.py包含乙個函式function1。

2.package2/__init__.py包含乙個類class1.

3.package2/subpackage1/module5.py包含乙個函式function2.

你可以通過這種方式將function1匯入package1/module1.py中:

這裡只使用乙個點,因為module2.py位於與當前模組相同的目錄中,當前模組是module1.py。

你可以將class1 和function2 以這種方式匯入package2/module3.py檔案中:

在第乙個匯入語句中,乙個點表示你正在從當前包匯入class1。別忘了,匯入乙個包基本上是匯入包的__init__.py檔案作為模組。在第二個匯入語句中,你將再次使用乙個點,因為subpackage1 與當前模組module3.py位於同乙個目錄中。

相對匯入的乙個明顯優勢是它們相當簡練。根據當前位置,它們可以將你之前看到的冗長的可笑的匯入語句轉換為如下簡單的語句:

不幸的是,相對匯入可能是混亂的,特別是對於目錄結構可能改變的共享專案。相對匯入也不像絕對匯入一樣可讀,而且很難識別匯入資源的位置。

來到絕對和相對匯入速成課程的結尾,很好!現在,你熟悉了匯入的工作原理。你已經學習了編寫匯入語句的最佳實踐,並且你知道絕對匯入和相對匯入之間的區別。

有了新的技能,你可以自信地從python標準庫、第三方包和自己的本地包匯入包和模組。記住,你通常應該選擇絕對匯入,而不是相對匯入,除非路徑是複雜的,並且會使宣告太長。

謝謝你的閱讀!

python 絕對匯入和相對匯入

今天在import自定義模組時遇到問題,在此記錄一下。假設檔案結構如下 project main.py utils a.py b.py 我想要實現乙個順序匯入main a b,即 main.py from utils import a a.py import b 然而在a.py報錯找不到b模組。因為...

python模組中的絕對匯入和相對匯入

在python的執行檔案或模組中,使用類似import 模組名 import 包名.模組名 from 包名.模組名 import 內容等匯入語法時,就是在用絕對路徑匯入模組。執行絕對匯入時的模組搜尋順序 執行檔案所在的目錄 執行檔案可以理解為入口指令碼,或者main函式所在的指令碼。pythonpa...

python之絕對匯入和相對匯入

這兩個概念是相對於包內匯入而言的。包內匯入即是包內的模組匯入包內部的模組。當前資料夾下 環境變數pythonpaht中 sys.path中 匯入當前模組同級別的模組 匯入當前模組同級別包中的模組 不能匯入具體的 變數 函式 型別 import匯入 sub package init py tools....