程式設計基礎 Python中的絕對匯入與相對匯入

2021-10-08 18:34:43 字數 4770 閱讀 4684

如果您從事的python專案有多個檔案,那麼您以前可能不得不使用import語句。即使對於擁有多個專案的python重度使用者(比如我),import也可能會造成混淆!您可能正在閱讀本文,因為您想對python中的import(尤其是絕對匯入和相對匯入)有更深入的了解。

在本教程中,您將學習兩者之間的區別以及它們的優缺點。讓我們潛入吧!

3 絕對import和相對import

4 參考

python模組是具有.py副檔名的檔案,而python包是其中具有模組的任何資料夾(或者在python 2中是包含__init__.py檔案的資料夾)。當乙個模組中的**需要訪問另一模組或程式包中的**時,你需要匯入它。

但是如何乙個模組,假設您像這樣匯入os模組:

import os
總結來說,python尋找乙個模組主要有以下三個步驟:

當python找到該模組時,它將其繫結到本地範圍內的乙個名稱。這意味著現在已經定義了os,並且可以在當前檔案中使用os,而不會丟擲modulenotfounderror。如果沒找到模組就丟擲modulenotfounderror,如下所示:

import os
但是要注意的另外乙個問題是,匯入模組,會出現安全問題。請注意,python的匯入系統存在一些重大的安全風險。這主要是由於其靈活性。例如,模組快取是可寫的,並且可以使用匯入系統覆蓋python的核心功能。從第三方程式包匯入還會使您的應用程式面臨安全威脅。

現在您知道了匯入語句的工作原理,讓我們**它們的語法。您可以匯入軟體包和模組。(請注意,匯入軟體包實際上是將軟體包的__init__.py檔案作為模組匯入。)您還可以從軟體包或模組中匯入特定的物件。

通常有兩種型別的匯入語法。直接使用模組時,可以直接匯入模組,如下所示:

import os
os可以是包或模組。當您使用第二種語法時,您將從另乙個包或模組中匯入。下面是是乙個例項

from os import path
path可以是模組,子包或物件,例如類或函式。您還可以選擇重新命名匯入的資源,如下所示:

import os as so
這將把匯入的os重新命名為so。現在必須將其引用為so,否則將無法識別它。

pep 8 是python的官方樣式指南,在編寫匯入語句時有一些提示。pep 8詳細見

總結如下:

匯入應始終寫在檔案頂部,在任何模組注釋和文件字串之後。

import應該根據用途分為以下三類:

每個import都要用空格分隔

在每個匯入組中按字母順序排列匯入也是乙個好主意。這使得查詢特定匯入變得更加容易,特別是當乙個檔案中有許多匯入時。以下是如何設定匯入語句樣式的示例。以下的import語句分為三個不同的組,用空格隔開。在每個組中,它們也按字母順序排列。

'''

格式化的import如下所示

'''# 標準庫

import datetime

import os

# 第三方庫

from flask import flask

# 本地庫

# import local_module

您已經掌握了如何編寫import語句以及如何像專業人士那樣設計它們的樣式。現在是時候學習一點關於絕對匯入的知識了。絕對匯入指定要匯入的資源使用其從專案根資料夾中的完整路徑。

假設您具有以下目錄結構:

└── project

├── package1

│ ├── module1.py

│ └── module2.py

└── package2

├── __init__.py

├── module3.py

├── module4.py

└── subpackage1

└── module5.py

當前目錄project其中包含兩個子目錄package1和package2。該package1目錄有兩個檔案,module1.py和module2.py。

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

讓我們假設以下內容:

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

from package1 import module1

from package1.module2 import function1

from package2 import class1

from package2.subpackage1.module5 import function2

module2中的內容如下:

def function1():

passs

package2中__init__.py中的內容如下:

class class1():

def __init__():

return

package2.subpackage1.module5中的內容如下:

def function2():

pass

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

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

但是,有時絕對匯入可能會變得非常冗長,具體取決於目錄結構的複雜性。想象一下這樣的宣告:

from package1.subpackage2.subpackage3.subpackage4.module5 import function6
太荒謬了吧?幸運的是,在這種情況下,相對匯入是乙個不錯的選擇!

相對匯入指定相對於當前位置(即import語句所在的位置)要匯入的資源。有兩種型別的相對匯入:隱式和顯式。隱式相對匯入在python3中已被棄用,因此我將不在這裡介紹它們。

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

from .some_module import some_class

from ..some_package import some_function

from . import some_class

您可以看到在上面的每個import語句中至少有乙個點。相對匯入使用點表示法來指定位置。

單點表示所引用的模組或軟體包與當前位置位於同一目錄中。兩個點表示它位於當前位置的父目錄中,即上面的目錄中。三個點表示它位於祖父母目錄中,依此類推。如果您使用類似unix的作業系統,這可能對您來說很熟悉!

假設您具有與以前相同的目錄結構:

└── project

├── package1

│ ├── module1.py

│ └── module2.py

└── package2

├── __init__.py

├── module3.py

├── module4.py

└── subpackage1

└── module5.py

您可以function1通過package1/module1.py以下方式匯入檔案:

# package1/module1.py

from .module2 import function1

你可以將class1和function2匯入到package2/module3.py檔案中:

# package2/module3.py

from . import class1

from .subpackage1.module5 import function2

在第乙個import語句中,單點表示您正在class1從當前包中匯入。請記住,匯入軟體包實際上會將軟體包的__init__.py檔案匯入為模組。

在第二個import語句中,您將再次使用乙個點,因為subpackage1它與當前模組位於同一目錄中module3.py。

當然這種方法有個極大問題,可能會報錯,如下所示:

modulenotfounderror: no module named '__main__.module2'; '__main__' is not a package
這是相對匯入只有在父模組已經在當前執行環境中被匯入過才有用,所以盡可能用絕對匯入。解決辦法見:

相對匯入的利與弊

相對匯入的乙個明顯優勢是它們非常簡潔。根據當前位置,他們可以將您之前看到的可笑的冗長的import語句變成如下所示的簡單內容:

from …subpackage4.module5 import function6

不幸的是,相對匯入可能會很混亂,尤其是對於目錄結構可能會更改的共享專案。相對匯入也不如絕對匯入更易讀,而且很難說出匯入資源的位置。

總的來說,通常應該選擇絕對匯入而不是相對匯入,除非路徑複雜並且會使語句過長。

《面向ArcGIS的Python指令碼程式設計》 導讀

前言 在過去的十多年裡,我在多所大學學習並講授了一系列gis課程。正是這樣一段經歷,促使我撰寫了這本書。在所有的課程中,有一課是 小 大用處 在dos系統時代,熟悉dos的人能使用命令列處理一些基本的任務。arcgis早期的桌面端軟體 arcinfo 除了使用arc巨集語言 aml 之外,在很大程度...

python導包 Python中包的匯入

15 june 2015 當你從python直譯器退出後再重新進入,之前所寫的 包括變數 函式都已經不存在了,如果你想週期性的執行這些功能但是並不想每次都將這些 重新輸入一遍,你可以將這些 儲存成檔案在本地進行儲存 也就是指令碼 當你寫的程式規模越來越大,維護起來越發吃力,你或許會想把它分割為不同功...

python中的settings使用絕對路徑

import os.path template dirs os.path.join os.path.dirname file templates replace 這個例子使用了神奇的 python 內部變數file,該變數被自動設定為 所在的 python 模組檔名。os.path.dirname ...