當前位置:
首頁 > 知識 > Python中的絕對導入和相對導入

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

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

打開今日頭條,查看更多精彩圖片

如果你做過有多個文件的Python項目,那麼你一定用過import語句。

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

關於Import的快速回顧

你需要對Python模塊和包有一個很好的理解,以了解導入的工作方式。Python模塊是一個擴展名是.py的文件,Python包是其中包含模塊的任何文件夾(或者,在Python 2中,是至少包含一個__init__.py文件的文件夾)。

當一個模塊中的代碼需要訪問另一個模塊或包中的代碼時,會發生什麼情況?導入它!

Import如何工作

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

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

Python要做的第一件事是查找sys.modules中的abc名稱。這是預先導入的所有模塊的緩存。

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

當Python找到該模塊時,將它綁定到本地作用域中的名稱。這意味著現在定義了abc,而且可以在當前文件中使用,而不引發NameError。

如果找不到該名字,會得到ModuleNotFoundError。你可以在Python文檔找到更多關於導入的信息!

注意:安全問題

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

導入語句語法

既然你知道導入語句是如何工作的,讓我們來探究它們的語法。你可以導入包和模塊。(注意,導入一個包基本上是導入包的__init__.py文件作為模塊。)還可以從包或模塊中導入特定的對象。

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

abc可以是一個包或一個模塊。

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

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

xyz可以是模塊、子包或對象,例如類或函數。你還可以重命名導入的資源,如:

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

這在腳本內將導入的資源abc重命名為other_name。它現在必須被引用為other_name,否則它將不被識別。

導入語句的風格

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

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

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

    • 標準庫導入(Python的內置模塊)

    • 相關第三方導入(已安裝且不屬於當前應用程序的模塊)

    • 本地應用程序導入(屬於當前應用程序的模塊)

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

在每個導入組中按字母順序排列導入也是一個好主意。這使得查找特定的導入更加容易,尤其是當文件中有許多導入時。

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

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

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

絕對導入

你已經掌握了如何編寫import語句以及如何像專業人士那樣設置樣式。現在是時候了解更多關於絕對導入的信息了。絕對導入從項目根文件夾中使用其完整路徑導入指定的資源。

語法與實例

假設你有以下目錄結構:

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

有一個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.

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

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

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

絕對導入的利弊

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

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

相對導入

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

語法與實例

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

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

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

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

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

回憶文件內容:

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

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

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

你可以將class1 和function2 以這種方式導入package2/module3.py文件中:

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

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

相對導入的利弊

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

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

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

結尾

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

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

謝謝你的閱讀!

小編註:

相對引用不僅僅是為了縮短引用路徑的長度,更多的是用於編寫庫(很多項目共用的軟體包)時使用。在庫軟體包中,庫代碼往往不知道自己會被用於何處、絕對路徑是什麼,只有使用相對引用,庫軟體包才能方便地被使用於各種不同的項目。

英文原文:https://realpython.com/absolute-vs-relative-python-imports/
譯者:張新英

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python部落 的精彩文章:

Python語言中字元串的拆分,連接及拼接

TAG:Python部落 |