一:python
中的模組和包
模組: 如果你從 python 直譯器退出後再重新進入, 那麼你之前定義的所有 (函式和變數) 都將丟失. 因此, 如果你想寫乙個更長的程式, 你最好離線地使用文字編輯器儲存成檔案,替代直譯器的輸入來執行. 這稱作建立乙個 指令碼 . 當你的程式變得更長, 你可能想把它分割成幾個檔案以能夠更簡單地維護. 你也許還想在幾個下同的程式裡使用寫過的程式, 而不用把一坨**拷來拷去.
為此 python 提供了方法, 能使使用者把定義存放在檔案裡, 同時又能在指令碼或互動式環境下方便的使用它們. 這樣的檔案稱為 模組 ; 乙個 模組 中的定義可以 匯入(import) 到另乙個模組或 主 模組 ( 主 模組是執行指令碼的最上層或計算模式下的一組可訪問變數的集合).
模組就是包含 python 定義和語句的檔案. 檔案的名字就是這個模組名再加上 .py. 在乙個模組中, 模組的名字 (乙個字串) 可以通過全域性變數 __name__ 得到.
包: 包是乙個有層次的檔案目錄結構,它定義了由n個模組或n個子包組成的python應用程式執行環境。通俗一點:包是乙個包含__init__.py 檔案的目錄,該目錄下一定得有這個__init__.py檔案和其它模組或子包。
包對應於資料夾,使用包的方式跟模組也類似,唯一需要注意的是,當資料夾當作包使用時,資料夾需要包含__init__.py檔案,主要是為了避免將資料夾名當作普通的字串。__init__.py的內容可以為空,一般用來進行包的某些初始化工作或者設定__all__值,__all__是在from package-name import *這語句使用的,匯出在__all__宣告過的模組。
二:模組的搜尋路徑
python在執行import語句時,到底進行了什麼操作,按照python的文件,它執行了如下操作:
第1步,建立乙個新的,空的module物件(它可能包含多個module);
第2步,把這個module物件插入sys.module中
第3步,裝載module的**(如果需要,首先必須編譯)
第4步,執行新的module中對應的**。(這裡提醒我們python模組中的**在被匯入時會被執行一次,但是只有在第一次被匯入時才會被執行)
第三步查詢module的過程
在import的第乙個階段,主要是完成了查詢要引入模組的功能,這個查詢的過程如下:
檢查 sys.modules (儲存了之前import的類庫的快取),如果module被找到,則⾛到第二步。
檢查 sys.meta_path。meta_path 是乙個 list,⾥面儲存著一些 finder 物件,如果找到該module的話,就會返回乙個finder物件。
檢查⼀些隱式的finder物件,不同的python實現有不同的隱式finder,但是都會有 sys.path_hooks, sys.path_importer_cache 以及sys.path。
丟擲 importerror。
三:匯入模組
通過以下例項來講解匯入,下面是乙個project的結構圖:(注:以下是在自定義的包中操作)
project/
packagea/
__init__.py
a.py
packageb/
__init__.py
b.py
bb.py
main.py
1. 如果想要呼叫同乙個包裡面的其他模組,如在packageb的bb.py中呼叫b.py的函式,需要使用如下方式匯入:
from packageb import b
或者
import b
(經過測試,這種寫法在pycharm中,會提示找不到模組b,但是你可以不用管這個,實際上可以執行)
2. 如果想要在不同包中呼叫其他模組中的函式,如在packageb的b.py中呼叫packagea中a.py的函式,需要使用如下方式匯入:
from packagea import a
或者import packagea.a`
3. 如果想要在外面的main.py中呼叫包中的函式或模組,如在mian.py中呼叫packageb中b.py的函式,需要使用
from packageb import b
或者import packageb.b`
4. 如果想要將乙個包中的所有模組匯入到另乙個模組中,如要在main.py中匯入packageb中所有的模組,需要使用:
from packageb import *
(注意:需要在packageb的__init__.py檔案加入__all__=[「需要匯入的模組名」])
`5. 如果使用下面的語句進行匯入:
import packageb`
packageb.bb.fuc() #這個會報錯
上面的這個import語句只會執行__init__.py檔案,而不會匯入任何模組。不過既然會執行__init__.py檔案那麼我們可以在改檔案中來進行一些操作。如
# packageb
# __init__.py
import b,bb
注意:無論乙個包的哪個部分被匯入, 在檔案__init__.py中的**都會執行.這個檔案的內容允許為空,不過通常情況下它用來存放包的初始化**。匯入過程遇到的所有 __init__.py檔案都被執行.
1. 相對引入:relative import 也叫作相對引入,在python2.5及之前是預設的引入方法。它的使用方法如下:
from .string import a
from ..string import a
from ...string import a
這種引入方式使用乙個點號來標識引入類庫的精確位置。與linux的相對路徑表示相似,乙個點表示當前目錄,每多乙個點號則代表向上一層目錄。
2. 我們來看看下面這段**:
# test.py
deffuc
(): print("in fuc")
print("in file test")
if __name__=="__main__":
fuc()
乙個模組既可以當作單獨的指令碼執行,也可以當作模組被匯入使用。當作為單獨的指令碼使用時,全域性變數__name__被置為__main__,if條件成立,那麼會執行if條件中的內容,這個作用可以用來測試指令碼**。
當作為模組被匯入使用時,__name__就會被置為模組名,而根據上面第二個說明,我們知道系統會執行一次該模組的**,此時print會輸出內容,而if條件不成立就不會在被執行了。
3. 如果乙個模組如果定義有列表__all__,則from module import *語句只能匯入__all__列表中存在的物件。如:
# test.py
__all__ = ["fuc1","fuc2"]
deffuc1
(): print("in fuc1")
deffuc2
(): print("in fuc2")
deffuc3
(): print("in fuc3")
此時如果在其他模組使用 from test import * ,那麼只能匯入fuc1 和 fuc2這兩個函式。
參考:
Python中的模組以及包
python包 1 import 方法 模組定義好後,我們可以使用 import 語句來引入模組 語法 import module1 module2 modulen 匯入python中的模組os math 開平方根 注意 乙個模組只會被匯入一次,不管你執行了多少次。這樣可以防止匯入模組被一遍又一遍地...
Python模組包中 init
在eclipse中用pydev開發python指令碼時,我遇到了乙個這樣的現象,當我新建乙個pydev package時,總會自動地生成乙個空的 init py檔案,因為是python新手,所以很不了解這個空檔案的作用是什麼,因為沒有什麼東西可寫在這裡,所以我直接把這個檔案給刪掉了,結果我的包圖示自...
Python模組包中 init
在eclipse中用pydev開發python指令碼時,我遇到了乙個這樣的現象,當我新建乙個pydev package時,總會自動地生成乙個空的 init py檔案,因為是python新手,所以很不了解這個空檔案的作用是什麼,因為沒有什麼東西可寫在這裡,所以我直接把這個檔案給刪掉了,結果我的包圖示自...