- 做過開發工作的童鞋應該都知道, 在一個完整的專案中, 會有大量的程式碼, 而且慢慢程式碼量會越來越多, 程式碼也就越來越難以維護;
- 隨著你的程式變得越來越長,你可能想要將它分割成幾個更易於維護的檔案。
- 你也可能想在不同的程式中使用順手的函式,而不是把程式碼在它們之間中拷來拷去
- 為了解決類似問題, 我們把很多功能相似的函式分組, 分別放到不同的檔案中,這樣每個檔案中的程式碼相對較少, 且函式功能相似;
- GitHub程式碼示例目地址
概述
模組簡述
- 在
Python
中提供了一個方法可以從檔案中獲取定義,在指令碼或者直譯器的一個互動式例項中使用, 這樣的檔案被稱為模組; - 模組中的定義可以匯入到另一個模組或主模組中(在指令碼執行時可以呼叫的變數集位於最高階,並且處於計算器模式)
- 模組是包括 Python 定義和宣告的檔案。檔名就是模組名加上 .py 字尾。
- 模組的模組名(做為一個字串)可以由全域性變數
__name__
得到 - 模組主要分為內建模組, 三方模組和自定義模組
模組優點
- 提高了程式碼的可維護性
- 提高了程式碼的服用度, 當一個模組完畢, 可以被多個地方引用
- 可避免函式名和變數名的衝突
標準庫模組
下面是一個使用python
標準庫中模組的例子
import sys
print('命令列引數如下:')
for i in sys.argv:
print(i)
print('\n\nPython 路徑為:', sys.path, '\n')
# 輸出結果如下
命令列引數如下:
../GitHub/PythonDemo/PythonStudy/7-模組/1-模組概述.py
Python 路徑為: ['/Users/../GitHub/PythonDemo/PythonStudy/7-模組', '/Users/../GitHub/PythonDemo/PythonStudy', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages', '/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend']
複製程式碼
argv
: 獲取命令列引數的列表import sys
引入python
標準庫中的sys.py
模組import
: 這是引入一個模組的方法(後面會提到)sys.path
: 包含了一個Python
直譯器自動查詢所需模組的路徑的列表
自定義模組
Python
中不但可以使用第三方模組和系統模組, 同時我們還可以使用自定義模組,- 在
Python
中一個.py
檔案就是一個模組 - 下面是我自定義的一個
Titan.py
模組, 程式碼如下
print('這是Titan模組')
# 定義變數
age = 20
name = 'titan'
# 定義方法
def sayGood():
print('good')
def sayNice():
print('nice')
def sayBad():
print('bad')
複製程式碼
匯入模組
import
方式
在Python
中匯入另一個檔案或者模組, 受用的語法是import
# 引入單個或多個模組
import module1[, module2[,... moduleN]
# 示例
# 一次匯入多個模組
import time, random, os
# 一次匯入一個模組
import calendar
複製程式碼
需要注意的是:
- 一個模組只會被匯入一次,不管你執行了多少次
import
, 可以防止模組被重複引用 - 引入任何模組時(包括自定義模組), 不用加
.py
字尾 - 當我們使用
import
語句的時候,Python
直譯器是怎樣找到對應的檔案的呢?- 這就涉及到
Python
的搜尋路徑,搜尋路徑是由一系列目錄名組成的,Python
直譯器就依次從這些目錄中去尋找所引入的模組。 - 這看起來很像環境變數,事實上,也可以通過定義環境變數的方式來確定搜尋路徑。
- 搜尋路徑是在
Python
編譯或安裝的時候確定的,安裝新的庫應該也會修改。搜尋路徑被儲存在sys
模組中的path
變數
- 這就涉及到
使用示例
import Titan
Titan.sayBad()
Titan.sayGood()
print(Titan.name)
# 輸出結果:
bad
good
titan
複製程式碼
from…import
方式
從模組中匯入一個指定的部分到當前的名稱空間, 同樣也可以匯入一個模組中的多個部分(或者匯入多個方法或變數), 格式如下:
from modname import name1[, name2[, ... nameN]]
複製程式碼
使用示例
from Titan import sayGood, sayBad, age
sayBad()
sayGood()
print(age)
# 輸出結果:
bad
good
20
複製程式碼
需要注意的是:
from…import*
方式
把一個模組中所有的內容, 全部倒入當前名稱空間, 但是最好不要過多地使用
# 格式:
from modname import *
# 使用:
from Titan import *
sayGood()
print(age)
複製程式碼
模組內建屬性和函式
__name__
屬性
- 除了包含函式定義外,模組也可以包含可執行語句, 這些語句一般用來初始化模組, 他們僅在第一次被匯入的地方執行一次
- 模組就是一個可執行的
.py
檔案, 一個模組唄另一個程式引用, 模組中的一些可執行語句便會執行 - 如果我們不想讓模組中的某些程式碼執行, 可以用
__name__
屬性來使程式僅呼叫模組中的一部分 - 現在我們將模組中的程式碼修改如下:
if __name__ == '__main__':
print('這是Titan模組')
else:
def sayGood():
print('good')
def sayNice():
print('nice')
def sayBad():
print('bad')
age = 20
name = 'titan'
複製程式碼
name
和main
前後都是雙下劃線- 每一個模組中都有一個
__name__
屬性, 當其值等於__main__
時, 表明該模組自身在執行, 否則被引入了其他檔案 - 當前檔案如果為程式的入口檔案, 則
__name__
屬性的值為__main__
dir()
函式
- 內建的函式
dir()
可以找到模組內定義的所有名稱, 以一個字串列表的形式返回 - 如果沒有給定引數,那麼
dir()
函式會羅列出當前定義的所有名稱
import Titan
print(dir(Titan))
# 輸出結果:
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'age', 'name', 'sayBad', 'sayGood', 'sayNice']
print(dir())
# 輸出結果:
['Titan', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
# 這裡定義一個新的變數
sum = 30
print(dir())
# 輸出結果:
['Titan', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'sum']
# 把定義的變數刪除後
del sum
print(dir())
# 輸出結果:
['Titan', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
複製程式碼
包
這裡我們先思考這樣一個問題: 在同一個專案中有兩個或兩個以上的開發者分別定義了相同名字的模組(當然獅子啊不同的目錄中, 同一個目錄下不可能建立出相同名字的檔案), 那麼模組該如何呼叫
解決
- 為了解決上述模組命名的衝突, 引入了按照目錄來組織模組的方法, 成為包
- 包是一種管理
Python
模組名稱空間的形式,採用"點模組名稱" - 引入包以後, 只要頂層的包不與其他人的發生衝突, 那麼模組就都不會與別人的發生衝突
- 所謂頂層的包指的是上一層的檔案目錄
- 同一個包可以包含多個模組
- 例如: 名為
A.B
的模組表示了名為A
的包中名為B
的子模組
需要注意的是:
在每一個包內(模組的同級目錄下)必須要建立一個名為__init__.py
的檔案, 主要是為了避免一些濫竽充數的名字, 目前該檔案內可以什麼都不用寫, 如圖所示:
呼叫方法
import a.Titan
import b.Titan
import b.coder
a.Titan.sayGood()
b.Titan.sayGood()
b.coder.sayGood()
# 輸出結果:
good--a
good--b
good--coder
複製程式碼
安裝使用第三方模組
pip
簡介
- 在
Python
中第三方庫是通過pip
安裝和管理的,pip
就像iOS
中的pod
一樣, 負責安裝和管理第三方庫 - 在
Mac
和Linux
系統中pip
是預設安裝過的, 一般無需重新安裝, 如有問題, 請自行百度解決 - 在
Mac
系統中會有一個預設的Python2.7
版本的, 我自己安裝了一個3.6的版本, 自然預設也安裝了pip
- 下面是一些
Python3.6
中pip
的命令, 這裡需要以pip3
為命令頭執行
# 檢視當前pip版本
pip3 -V
# 安裝第三方庫
pip3 install ...
# 對pip進行升級
pip3 install --upgrade pip3
複製程式碼
安裝第三方庫
Mac
系統安裝第三方庫, 直接開啟終端執行安裝命令即可Pillow
已經是Python
平臺事實上的影像處理標準庫了PIL
功能非常強大,但API
卻非常簡單易用
pip3 install Pillow
複製程式碼
第三方模組的使用
操作影像
下面是最常見的影像縮放操作示例程式碼
from PIL import Image
# 開啟一個jpg影像檔案,注意是當前路徑:
im = Image.open('titan.jpg')
# 獲得影像尺寸
w, h = im.size
print('image size: %sx%s' % (w, h))
# 縮放到50%:
im.thumbnail((w//2, h//2))
print('image to: %sx%s' % (w//2, h//2))
# 把縮放後的影像用jpeg格式儲存:
im.save('jun.jpg', 'jpeg')
複製程式碼
其他功能如切片、旋轉、濾鏡、輸出文字、調色盤等一應俱全, 程式碼如下:
from PIL import Image, ImageFilter
# 開啟一個jpg影像檔案,注意是當前路徑:
im = Image.open('jun.jpg')
# 應用模糊濾鏡:
im2 = im.filter(ImageFilter.BLUR)
im2.save('jun1.jpg', 'jpeg')
複製程式碼
相關參考