一、模塊化
- 一般來說,編程語言中,庫、包、模塊是同一種概念,是代碼組織方式
- python中只有一種模塊對象,但是為了模塊化組織模塊的便利,提供了一個概念-包、模塊是同一種概念,是代碼組織方式
- 模塊module,指的是python的源代碼文件
- 包package,值的是模塊組織在一起的和包名同名的目錄及其相關文件
二、導入語句
- import 模塊1,模塊2 : 模塊完全導入
- import...as... : 模塊別名
1、import語句
- 找到指定的模塊,加載和初始化它,生成模塊對象,找不到,拋出ImportError異常;在import所在的作用域的局部命名空間中,增加名稱和上一步創建的對象關聯
import functools # 導入頂級模塊 import os.path #導入非頂級模塊 print(dir()) print(functools) 導入頂級模塊,其名稱會加入到本地名稱空間中,並綁定到其模塊對象 導入非頂級模塊,將其頂級模塊加入到本地名稱空間中,導入的模塊必須使用完全限定名來訪問 如果使用了as,其后的名稱直接加入到本地名稱空間中,並直接綁定到導入的模塊對象
2、from...import 部分導入
- from...import...as... 別名
- from pathlib import Path,PosixPath # 在當前名稱空間導入該模塊指定的成員
- from pathlib import * #在當前名稱空間導入該模塊所有公共成員
- from functools import wraps as wr #別名
舉例1: from os.path import exists #加載,初始化os.path模塊,exists加入本地名稱空間並綁定 if exists('c:\'): print('Found') else: print('Not Found') print(dir()) print(exists) 找到from子句中指定的模塊,加載並初始化它 對應import子句后的名稱 1、先查form子句導入的模塊是否具有該名稱的屬性 2、如果不是,則嘗試導入該名稱的子模塊 3、還沒找到,則拋出ImportError異常 4、這個名稱保存到本地名稱空間中,如果有as子句,則使用as子句后的名稱
三、自定義模塊命名規范
- 1、模塊名就是文件名
- 2、模塊名必須符合標識符的要求,非數字開頭的字母數字和下划線的組合
- 3、不要使用系統模塊名,避免沖突,除非你明確知道這個模塊名的用途
- 4、通常模塊名為全小寫,下划線來分割
四、模塊搜索順序
1、使用sys.path查看搜索順序
import sys for p in sys.path: print(p) 執行輸出: c:\users\administrator\appdata\local\programs\python\python35\python35.zip c:\users\administrator\appdata\local\programs\python\python35\DLLs c:\users\administrator\appdata\local\programs\python\python35\lib c:\users\administrator\appdata\local\programs\python\python35 c:\users\administrator\appdata\local\programs\python\python35\lib\site-packages c:\users\administrator\appdata\local\programs\python\python35\lib\site-packages\IPython\extensions C:\Users\Administrator\.ipython 顯示結果為,python模塊的路徑搜索順序,當加載一個模塊的時候,需要從這些搜索路徑中從前到后依次查找 不搜索這些目錄的子目錄,搜索到就加載,搜索不到就拋異常
2、路徑順序
- 程序主目錄,程序運行的主程序腳本所在的目錄
- PYTHONPATH目錄,環境變量PYTHONPATH設置的目錄也是搜索模塊的路徑
- 標准庫目錄,python自帶的庫模塊所在的目錄
3、模塊的重復導入
- 所有加載的模塊都會記錄在sys.modules中,sys.modlues存儲已經加載過的所有模塊的字典,所以不存在重復導入
4、模塊運行
- __name__,每個模塊都會定義一個__name__特殊變量來存儲當前模塊的名稱,如果不指定,則默認為源代碼文件名詞,如果是包則有限定名解釋器初始化的時候,會初始化sys.modules字典(保存已加載的模塊),創建builtins模塊,
- __main__模塊,sys模塊,以及模塊搜索路徑sys.path
5、if __name__ == '__main__':用途
- 本模塊的功能測試,測試本模塊內的函數
- 避免主模塊變更的副作用,頂層代碼沒有封裝,主模塊使用沒有問題,但是,一旦有了新的主模塊,當前模塊要被導入,由於原來代碼沒有封裝,一並執行了
五、模塊的屬性
- __file__ : 字符串,源文件路徑
- __cached__: 字符串,編譯后的字節碼文件路徑
- __spec__ : 顯示模塊的規范
- __name__ : 模塊名
- __package__ : 當模塊是包,同__name__,否則,可以設置為頂級模塊的空字符串
1、包package特殊的模塊
模塊和包的總結:
- 包能更好的組織模塊,尤其是大模塊代碼很多,可以拆分成很多子模塊,便於使用某些功能就加載相應的子模塊;
- 包目錄中__init__.py是在包第一次導入的時候就會執行,內容可以為空,也可以是用於該包初始化工作的代碼,最好不要刪除它;
- 導入子模塊一定會加載父模塊,但是導入父模塊一定不會導入子模塊,包目錄之間只能使用點作為間隔符,表示模塊及其子模塊的層級關系
- 模塊也是封裝,如同類,函數。不過他能夠封裝變量,類,函數
- 模塊就是名稱空間,其內部的頂層標識符,都是他的屬性,可以通過__dict__或dir()查看
六、絕對導入和相對導入
1、絕對導入
- 在import語句或者from導入模塊,模塊名稱最前面不是以點開頭的是絕對導入
- 絕對導入總是去搜索模塊搜索路徑中找
2、相對導入
- 只能在包內使用,且只能用在from語句中,使用.點號,表示當前目錄內
- ..表示表示上一級目錄,不要在頂層模塊中使用相對導入