Python——模塊 [ 筆記 ]


01. 模塊化(module)程序設計概念

模塊和包概念的進化史

  程序越來越複雜,語句 多了,我們會將實現同一個功能的語句封裝到函數中,統一管理和調用,於是 “函數” 誕生了。

  程序更加複雜,函數和變量 多了,我們將同一類型對象的“數據和行爲”,也就是“變量和函數”,放到一起統一管理和調用,於是 “類和對象” 誕生了。

  程序繼續複雜,函數和類 更加多了,我們將實現類似功能的函數和類統統放到一個模塊中,於是 “模塊” 誕生了。

  程序還要複雜,模塊 多了,我們將實現類似功能的模塊放到一起,於是 “包” 就誕生了。
pic01

  1. Python 程序由模塊組成。一個模塊對應 python 源文件,一般後綴名是:.py。
  2. 模塊由語句組成。運行 Python 程序時,按照模塊中語句的順序依次執行。
  3. 語句是 Python 程序的構造單元,用於創建對象、變量賦值、調用函數、控制語句等。

標準庫模塊(standard library)

  與函數類似,模塊也分爲 標準庫模塊用戶自定義模塊

  Python 標準庫提供了操作系統功能、網絡通信、文本處理、文件處理、數學運算等基 本的功能。比如:random(隨機數)、math(數學運算)、time(時間處理)、file(文件處理)、 os(和操作系統交互)、sys(和解釋器交互)等。

  另外,Python 還提供了海量的第三方模塊(即用戶自定義模塊),使用方式和標準庫類似。功能覆蓋了我們 能想象到的所有領域,比如:科學計算、WEB 開發、大數據、人工智能、圖形系統等。

爲什麼需要模塊化編程

  模塊(module)對應於Python源代碼文件(.py文件)。模塊中可以定義變量、函數、類、普通語句。這樣,我們可以將一個 Python程序分解成多個模塊,便於後期的重複應用。
  模塊化編程(Modular Programming)將一個任務分解成多個模塊。每個模塊就像一個積木一樣,便於後期的反覆使用、反覆搭建。

  模塊化編程有如下幾個重要優勢

  1. 便於將一個任務分解成多個模塊,實現團隊協同開發,完成大規模程序
  2. 實現代碼複用。一個模塊實現後,可以被反覆調用。
  3. 可維護性增強。

模塊化編程的流程

  1. 設計 API(Application Programming Interface,應用程序編程接口),進行功能描述。
  2. 編碼實現 API 中描述的功能。
  3. 在模塊中編寫測試代碼,並消除全局代碼。
  4. 使用私有函數實現不被外部客戶端調用的模塊函數。

  每個模塊都有一個名稱,通過特殊變量 __name__ 可以獲取模塊的名稱。在正常情況下,模塊名字對應源文件名。
  僅有一個例外,就是當一個模塊被作爲程序入口時(主程序、交互式提示符下),它的__name__的值爲 “__main__”

# 設計計算薪水模塊的API

'''
    用於計算公司員工的薪資
'''

company = 'kuiuz'

def yearSalary(monthSalary):
    '''根據傳入的月薪的值,計算出年薪:monthsalary*12'''
    return monthSalary*12

def daySalary(monthSalary):
    '''根據傳入的月薪值,計算出一天的薪資,一個月按22.5天計算(國家規定的工作日)'''
    return monthSalary/22.5
# 通過__doc__獲得模塊的文檔字符串的內容
import Salary
print(Salary.__doc__)
print(Salary.daySalary.__doc__)

02. 模塊的導入

import語句導入

  • import 語句的 基本語法格式 如下:
     import 模塊名 #導入一個模塊
     import 模塊 1,模塊 2… #導入多個模塊
     import 模塊名 as 模塊別名 #導入模塊並使用新名字
  • import 加載的模塊分爲 四個通用類別
     ① 使用 python 編寫的代碼(.py 文件);
     ② 已被編譯爲共享庫或 DLL 的 C 或 C++擴展;
     ③ 包好一組模塊的包
     ④ 使用 C 編寫並鏈接到 python 解釋器的內置模塊;

from…import導入

  Python 中可以使用 from…import 導入模塊中的成員。基本語法格式如下:

from 模塊名 import 成員 1,成員 2,…

  如果希望導入一個模塊中的所有成員,則可以採用如下方式:

from 模塊名 import \*

【注】儘量避免“from 模塊名 import * ”這種寫法。\* 它表示導入模塊中所有的不是以下劃線(_)開頭的名字都導入到當前位置。 但你不知道你導入什麼名字,很有可能會覆蓋掉你之前已經定義的名字,而且可讀性極其的差。

import()動態導入

  import 語句本質上就是調用內置函數__import__(),我們可以通過它實現動態導入。給 __import__()動態傳遞不同的的參數值,就能導入不同的模塊。
  注意:一般不建議我們自行使用__import__()導入,其行爲在 python2 和 python3 中 有差異,會導致意外錯誤。如果需要動態導入可以使用 importlib 模塊:importlib.import_module(模塊名)

import 語句和 from…import 語句的區別

  import 導入的是 模塊。from…import 導入的是 模塊中的一個函數/一個類
  如果進行類比的話,import 導入的是 “文件” ,我們要使用該“文件”下的內容,必須前面加“文件名稱”。from…import 導入的是文件下的 “內容” ,我們直接使用這些“內容”即可,前面再也不需要加“文件名稱”了。

模塊的加載問題

  一個模塊無論導入多少次,這個模塊在整個解釋器進程內有且僅有一個實例對象。

重新加載:
  有時候我們確實需要重新加載一個模塊,這時候可以使用:importlib.reload() 方法。


03. 包(package)的使用

包(package)的概念和結構

  當一個項目中有很多個模塊時,需要再進行組織。我們將功能類似的模塊放到一起, 形成了“包”。本質上,“包”就是一個必須有 __init__.py 的文件夾。
  包下面可以包含 “模塊(module)”,也可以再包含 “子包(subpackage)”。就像文件夾下面可以有文件,也可以有子文件夾一樣。

導入包操作和本質

pic02

  1. from package import item 這種語法中,item 可以是包、模塊,也可以是函數、類、變量。
  2. import item1.item2 這種語法中,item 必須是包或模塊,不能是其他。導入包的本質其實是“導入了包的__init__.py”文件。也就是說,”import pack1”意味 着執行了包 pack1 下面的__init__.py 文件。 這樣,可以在__init__.py 中批量導入我們需要 的模塊,而不再需要一個個導入。

__init__.py 的三個核心作用:

  1. 作爲包的標識,不能刪除。
  2. 用來實現模糊導入
  3. 導入包實質是執行__init__.py 文件,可以在__init__.py 文件中做這個包的初始化、以及需要統一執行代碼、批量導入。

用*導入包

  Python 提供一個明確的包索引。 這個索引由 __init__.py 定義 __all__ 變量,該變量爲一列表,如上例 a 包下的 __init__.py 中,可定義 __all__ = [“module_A”,“module_A2”]
  這意味着, from sound.effects import * 會從對應的包中導入以上兩個子模塊,即 * 代表__all__定義的內容。
  【注】儘管提供 import * 的方法,仍不建議在生產代碼中使用這種寫法。

包內引用

  • from … import module_A   #…表示上級目錄 ( 2個.)
  • from . import module_A2   #.表示同級目錄 (1個. )

sys.path 和模塊搜索路徑

  當我們導入某個模塊文件時, Python 解釋器一般按照如下路徑尋找模塊文件(按照順序尋找,找 到即停不繼續往下尋找):

  1. 內置模塊
  2. 當前目錄
  3. 程序的主目錄
  4. pythonpath 目錄(如果已經設置了 pythonpath 環境變量)
  5. 標準鏈接庫目錄
  6. 第三方庫目錄(site-packages 目錄)
  7. .pth 文件的內容(如果存在的話)
  8. sys.path.append()臨時添加的目錄

  當任何一個 python 程序啓動時,就將上面這些搜索路徑(除內置模塊以外的路徑)進行收集, 放到 sys 模塊的 path 屬性中(sys.path)。

使用 sys.path 查看和臨時修改搜索路徑:

sys.path.append(路徑)

04. 模塊的發佈和安裝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章