Python 初學第十三講—模組
善用前人或過去的自己所寫的程式碼,讓工作事半功倍
Python 擁有許多強大的模組,像是數據分析用的 numpy
、機器學習用的 keras
、方便我們處理文件目錄的 os
、或是爬取資料時常用的 requests
等等。
今天本篇文章將會提及該如何使用這些強大的資源,以及該如何自己動手寫一個 module。
如何才能站在巨人的肩膀上
install package/module
當我們需要使用別人所寫好的模組之前,依據不同的情況可能會使用以下幾種不同的安裝方式。若你的 Python 環境是從官方網站下載,可能會在命令提示字元(Windows)/終端機(Mac)當中使用 pip
作為下載模組的工具:
pip install [module]
但若你的 Python 環境是利用 Anaconda、Miniconda 等軟體建置的,那麼就必須開啟 conda
的命令列,並且使用 pip
或是 conda
的下載途徑:
conda install [module]
若以上方法不可行,就必須要手動下載模組的 package 並且建置路徑,方法在此不進行贅述。
import 語句
我們成功在環境當中新增可使用的模組以後,使用時透過 import
語法來讓程式取得我們所 import 的程式碼並執行。
方法一:import [module] (as [name])
最常用的方法就是 import [module]
,也就是將我們所要引入的 module
裡面的所有程式碼 import 進來,因此可以在 import 以後使用該模組裡的所有變數、函式等等。
在 Python 當中,有一個相當實用的模組叫做 random
,顧名思義是以產生隨機數字、隨機抽樣等等功能著名的模組。舉例來說,當我們今天想要使用這個模組,隨機地在 1 到 100 之間抽出一個數字時,可能會寫出如下的程式碼:
import random
print(random.randint(1, 100))
我們首先將所需要使用的模組 random
給 import 進來,接著使用 random.
來使用 random
模組當中的 randint
函式,意即在範圍內隨機抽出一個整數,並將範圍指定在 1 到 100 之間。執行結果如圖:
由此可見,當我們直接使用 import [module]
時,若需要使用在 module 當中的變數或是函式時,就需要使用 [module].
來使用該變數或是函式。可以將這個 .
視為我們要告訴電腦說,當執行到這一句程式碼時,請從這個 module 拿出我所指定的變數。
當然,有時我們難免會覺得每次都要寫 random.
來使用有些太過麻煩,尤其是當 module 本身的名字太長時、或是避免與原本的程式碼有名稱重複的問題時,可能會改成使用以下的寫法:
import random as rm
print(rm.randint(1, 100))
我們在引入 random
模組時,同時將其重新命名為 rm
,然後再繼續使用方才的 .
方法來使用當中的內容。執行結果如下:
一般來說,我們在網路上看到別人的程式碼時,也經常看到這種 import [module] as [name]
的寫法,像是 import numpy as np
、或是 import pandas as pd
,到後來大部分的人在 import
一些特定的 module
時,可能都會使用相同的縮寫或是名稱,如方才所提到的 numpy as np
以及 pandas as pd
等。
方法二:from [module] import [variable/function]
然而,有些好用的 module 是相當龐大的,如果每一次都要將整個 module 的內容 import 進來,勢必會降低許多程式運行上的效能。
因此,Python 也提供了另一個讓我們使用模組的方法:
from [module] import [variable/function]
直接就程式碼來看,就是指我們想要導入特定的變數或是函式來使用,然後指定這些變數或是函式的來源模組。我們同樣使用上面 random
的例子,隨機地在 1 到 100 之間抽出一個數字,此時我們可以將程式碼改寫如下:
from random import randint
print(randint(1, 100))
意即我們從 random
模組當中把 randint
這個函式導入,如此一來 randint
這個函式就等同於在這份程式碼裡完成宣告,也就不需要透過 module.
來取用了,可以直接使用,而執行結果如下:
如何使用自己所寫的程式碼?
有時候我們不只是要使用別人寫好的程式碼,而是在完成專案時,為了整理方便而將 code 拆成不同份、或是單純需要使用自己過去所寫的 code 的話,就必須要自己寫一個 module。
舉例來說,若我們今天寫了如下的程式碼,並且命名為 sample.py
:
name = 'ccClub'def my_func():
print('Hi')
此時若我們想要使用方才所寫的 sample.py
在我們的程式碼當中,最簡單的方法是將此檔案與我們現在的程式碼放在同一個路徑,使用範例如下:
import sample
sample.my_func()
print(sample.name)
而執行結果如下:
然而,我們不可能總是把所有的程式碼放在同一個路徑或是資料夾。這時,為了要讓這一份程式碼變的能在同一個環境底下任何時候都能使用,我們就需要將這份檔案放到 Python 環境的路徑。
為了要找到環境的路徑,需要使用 sys
這個 module,利用 sys.path
來找到環境路徑。
import sys
print(sys.path)
輸出結果可能為 ~/lib/python3.6/site-packages
,波浪號為個人 Python 環境安裝的路徑。找到此路徑以後,將剛才的 sample.py
移至該路徑,然後就可以直接在任何程式當中 import 這個 module。
Package vs. Module
除此之外,有時我們可能需要將類似功能的 module 整合在一起,或是為了做到較好的模組化而將程式碼分成不同的 module。此時我們就需要使用到 package
的概念。
舉例來說,我們大多數經由 pip install
而來的這些模組,比如 scikit-learn
等等都是各式各樣的 package,是一個較為龐大的目錄,而 module 指的就是其中的一個檔案。
package 可以簡單地被視為一個資料夾,而要讓電腦認為這是一個可以被 import 的 package 的話,就必須要存在一個 __init__.py
檔案,此檔案可以為空,或是寫入任何該 package 或是 package 中的 module 被 import 時要執行的程式碼。
以 Python module document PEP 328 提供的範例概念圖為例:
package
├── __init__.py
├── subpackage1
│ ├── __init__.py
│ ├── moduleX.py
│ └── moduleY.py
├── subpackage2
│ ├── __init__.py
│ └── moduleZ.py
└── moduleA.py
此 package 包含了兩個子 package 以及 moduleA,而子 package 底下還包含了 moduleX、Y、Z。若要從這個 package 當中 import 任何一個 module,就必須要使用以下的程式碼:
import [package].[module]
與 module 的 import 相同,要利用 .
來作為進到下一層的方法。同時除了上述的用法以外,也可以使用 from [package].[module] import [method]
來使用 module 當中的變數或是函式。
什麼是 if __name__ == ‘__main__’ ?
在學習 Python 的過程中,我們經常會在各式各樣的範例程式碼當中看到如下的語法:
if __name__ == '__main__':
# any python statement
如果你曾經學過其他程式語言,那麼對於 main function
的概念應該並不陌生,就是執行一個 script 時會被呼叫的主程式。那麼在 Python 裡面的 __name__ == '__main__'
又是什麼意思呢?其實這個問題的答案很簡單,當我們今天寫了一份程式碼叫做 sample.py
,內容如下:
if __name__ == '__main__':
print("Running sample.py")
else:
print("Running other script")
當我們在命令列執行 $python sample.py
時,結果如下:
Yu-Hsuande-MacBook-Air:ccClub yuhsuan$ python sample.py
Running sample.py
若使用 jupyter notebook
,在當中利用 !
來執行 cmd 命令,當我們執行 ! python sample.py
時,結果如下:
然而,當我們寫了另一份程式碼 import_sample.py
,內容如下:
import sample
print("This is import sample.")
當我們直接執行這個 import_sample.py
,得到的結果如下:
Yu-Hsuande-MacBook-Air:ccClub yuhsuan$ python import_sample.py
Running other script
This is import sample.
注意到了嗎?當我們直接執行 sample.py
時,得到的輸出是 Running sample.py
,但是當我們執行的是 import_sample.py
時,得到的輸出卻是 Running other script
。
也就是說 if __name__ == '__main__'
是用於判斷此程式是否正在被做為主程式來執行(意即直接在命令列執行 python script.py
等等)。若是,則將會執行此 if 底下的程式碼,若否,則視 else 的有無來決定。
小結
在 Python 這樣一個以 module 帶給大家方便的程式語言來說,學會如何使用模組是十分重要的。然而,在使用以及安裝的過程當中也十分容易遇到各式各樣的問題以及錯誤,因此學會使用的同時,也必須學會如何在網路上搜尋到適合自己電腦環境的安裝方式以及除錯方式。
我們是 ccClub 團隊,致力於讓 Python 成為大家的第二外語,希望能用淺顯易懂、循序漸進的方式,帶領新手一步步跨入程式設計的世界。
如果你喜歡這篇文章,請給我們 1~10 個掌聲。
如果你喜歡「Python初學」的教學系列文,請給我們 11 個以上的掌聲。
Facebook: ccClub Python讀書會