python深入之包和模組的匯入機制(重點)

2021-08-22 13:20:54 字數 3064 閱讀 6848

關於模組匯入時模組底層做的事情

(1)第一次匯入模組:底層做了3件事情,1.在自己的命名空間執行被匯入模組中的所有**;2.以模組名為名稱建立乙個模組物件,並將模組中所有的頂級變數(包括變數和函式)以屬性的形式繫結在該模組物件上;3.在import位置引入該物件名稱到當前命名空間。這裡,在當前命名空間使用被匯入模組中的屬性時要使用「.」語法的原因,就可以解釋為要使用乙個物件的某個屬性,就必須使用「物件.屬性」的形式

(2)第二次匯入模組:直接執行第3步,即在import位置引入該物件名稱到當前命名空間。原因是第一次匯入之後,已經將前兩步執行的結果儲存到記憶體中,第二低匯入時直接到相應的記憶體尋找即可,不需浪費更多記憶體於此。因此,第二次匯入速度更快,且更節省記憶體

(3)import m和from a import b兩種匯入方式在底層執行機制的異同(重點):兩種匯入方式第一次匯入都會執行上述3步,第二次或更多次匯入則只會執行第三步,所以兩種匯入方式沒有誰比誰更節省記憶體之說,不要認為後者只是匯入了模組中的一部分就覺得後者比較省記憶體,其實際是都會首先執行被匯入模組中的所有內容,佔的記憶體是相同的,區別在於是拿被匯入模組中的哪些部分到當前命名空間中進行使用

關於被匯入模組位置的檢索

(1)第一次匯入模組:按照模組檢索路徑順序去尋找,即第一級是內建模組,如sys模組,這類模組優先順序最高;第二級是sys.path路徑列表。其中sys.path路徑列表路徑列表由四部分組成,分別是1.當前目錄;2.環境變數pythonpath中指定的路徑列表;3.指定路徑下的.pth檔案中的檔案路徑列表;4.python的安裝路徑及其中的lib庫

(2)修改模組檢索路徑

二.直接在環境變數pythonpath中的路徑列表中新增路徑。在電腦設定環境變數中可以進行新增,這裡是在「使用者變數」一欄中對pythonpath進行新增,以及新增其值為需要的模組路徑,新增完後,路徑會自動出現在sys.path路徑列表當中

三.新增.pth檔案。.pth檔案要在指定的特殊位置進行新增,這裡需要使用site模組中的geisitepackage()方法進行指定特殊位置的查詢,一般是python安裝路徑和安裝路徑中lib目錄下的site-package目錄這兩個位置。在這兩個位置其中乙個裡面建立.pth檔案,並在檔案中新增需要的路徑,如果要新增多個路徑,通過換行即可。之後改路徑會自動出現在sys.path路徑列表當中

(3)sys.path路徑列表中的優先順序(重點):當前目錄--環境變數pythonpath--python安裝目錄--python安裝目錄中的.pth檔案--site-package目錄--site-package目錄中的.pth檔案

(4)第二次匯入模組:直接到載入過的模組群中去找,這裡需要使用sys模組中的modules屬性來檢視哪些模組是被載入過的

關於匯入模組的常見場景

(1)區域性匯入:即在某些區域性範圍內(小的命名空間)中對一些模組進行匯入,避免耗時。原因在於一旦對某個模組進行匯入,就會先去執行該模組的所有內容,如果該模組內容繁多,而在當前命名空間中又只在少數地方會用到該模組,就應該在用到該模組的命名空間中再對其進行匯入,避免一開始就用掉很多記憶體,且比較耗時。需要注意,區域性匯入的模組只能在區域性使用,外部不能使用,如:

def run():

import other

print(other.o1)

print(other.o2)

這裡只有在呼叫run()方法時才會用到other模組的內容,故只在run()方法內部進行模組的匯入,也只能在run()方法內部使用,其他地方不能使用

(2)覆蓋匯入:即自定義模組與其他模組重名時,其匯入遭到覆蓋的情況。有兩種情況,1.自定義模組與非內建模組重名,則由優先順序別的高低,可能會被覆蓋;2.自定義模組與內建模組重名,則一定會被覆蓋,這裡可以使用from a import b的匯入形式對與內建模組重名的模組進行匯入

(3)迴圈匯入:有兩個模組a和b,在a中匯入了b,在b中又匯入了a,這就是迴圈匯入。迴圈匯入會導致最終的結果出現錯誤,舉個例子詳細說明:

兩個模組分別是test和other,test模組中的內容是:

t1 = "t1"

t2 = "t2"

import other

print(other.o1)

print(other.o2)

other模組中的內容是:

o1 = "o1"

o2 = "o2"

import test

print(test.t1)

print(test.t2)

執行test模組,得到的結果是:

o1o2

t1t2

o1o2

其中的執行過程詳解:1.執行test中的**,直到import other;2.去sys.modules中尋找other模組是否已經被載入過,這裡都是第一次匯入,other沒有載入過,去檢索路徑尋找other模組,執行其中**,並將其中的頂層變數o1和o2以屬性的形式繫結在other物件上,存入sys.modules中;3.執行other**到import test,重複2中內容,將繫結了t1和t2的test物件存入sys.modules;4.執行test**到import other,這時,other是已經載入過的模組,並且繫結了o1和o2兩個屬性,在sys.modules中找到other模組後,不再去路徑列表中尋找,直接執行其下的print(other.o1)和print(other.o2)語句,列印出o1和o2;5.4完成即是3中的import test完成,繼續後面的print(test.t1)和print(test.t2)語句,列印出t1和t2;6.5完成即是1中的import other完成,繼續執行後面的print(other.o1)和print(other.o2)語句,再次列印出o1和o2,即為最後的結果

迴圈匯入問題的解決方案:避免出現迴圈匯入,將內容放到其他模組中,再分別進行匯入即可,這樣就不會出現兩個模組相互匯入的情況

(4)可選匯入:即兩個功能相近的模組,根據需要選擇其中乙個進行匯入。使用場景是想要優先選擇a模組,但是要在沒有a模組的情況下,將b模組當作備用,實現**如下:

try:

import a as o

except modulenotfounderror:

import b as o

print(o.o1)

給兩個模組取相同的別名,這樣不管是用哪乙個,都可以統一使用同乙個名字來呼叫,增加了**的擴充套件性

python導模組和包

1 python中的模組 python模組,是乙個python檔案,以.py結尾,包含了python物件的定義和python語句。2 python中的包 包就是資料夾,但該資料夾下必須存在init.py 檔案,該檔案的內容可以為空。直接匯入模組 import time 直接匯入包 import se...

python深入之包和模組,包和模組的匯入方式

關於包和模組 2 包 是乙個有層級的目錄結構,包含n個模組或者n個子包,包中一定要有 init py檔案 3 庫 是完成一定功能的 集合,表現形式是乙個模組,或包 4 框架 是乙個架構層面的概念,為解決乙個開放性問題而設計的具有一定約束性的支撐結構,通過框架可以快速實現乙個解決問題的骨架,後面按照框...

python深入之包內的模組匯入

關於包內匯入的概念和分類 1 包內匯入 即在乙個包的內部,存在某個模組匯入了其他在該包內部的模組 2 包內匯入分類 絕對匯入和相對匯入。絕對匯入即是使用絕對路徑進行匯入,如import 包.模組 相對匯入即是使用 或 來表示相對路徑進行匯入,表示根據模組名稱獲取的當前目錄,表示根據模組名稱獲取的上級...