模組與 import 陳述式

  • 用多個檔案來建立並使用 Python 程式
  • 所謂的模組(module),只是一個 Python 程式檔
  • 按層次來架構
    • 程式碼:資料類型(單字) → 陳述式(句子) → 函式(段落) → 模組(章節)
  • 在程式中,參考其他模組的程式
    • 就像比喻:在本書中參考第八章解釋
    • 要參考其他模組的程式:使用 import 陳述式 → 讓你的程式使用「被匯入模組裡面的程式與變數」

匯入模組

  • import 陳述式最簡單的用法是:import module
  • 其中 moudle 是其他的 Python 檔,不包括 .py 副檔名

【案例一】模擬一個氣象站,並印出一個氣象報告

1.撰寫主程式、獨立的模組

  1. 用一個主程式來印出報告
  2. 以及一個獨立的模組 → 裡面有一個函式,會回傳供報告使用的氣象狀況

主程式(weatherman.py)

在 import 陳述式之後,主程式就可以使用模組(report.py)內的所有東西,只要在它的名稱前面使用「模組名稱.」 (report.)

import 模組名稱
description = 模組名稱.get_description()
print("文字:", description)
#在 import 陳述式之後,主程式就可以使用 report.py 內的所有東西,只要在它的名稱前面使用 report. 即可

import report                             # 匯入整個 report 模組

description = report.get_description()    # 匯入整個 report 模組,但需要在 get_description() 前面使用 report.
print("Today's weather:", description)

模組(report.py)

用模組的名稱來限定模組的內容,所以「可以避免名稱衝突」。別的地方也有可能會有 get_description() 函式,但不會不小心呼叫它

def get_description():
    """文字"""
    from 模組名稱 import 函式名稱
    串列名稱 = ['字串1', '字串2', '字串3', '字串4', '字串5', '字串6']
    return 函式名稱(串列名稱)
def get_description():    # see the docstring
    """Return random weather, just like the pros"""
    from random import choice
    possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']
    return choice(possibilities)

2.將兩個檔案放在同一個目錄下

  1. 指示 Python 將 weatherman.py 當成主程式來執行 → 它會存取 report 模組,並執行它的 get_description()函式
  2. 主程式會取回並印出的東西 → 編寫 get_description() 來回傳一串串列內的隨機結果
python weatherman.py
Today's weather: sleet

python weatherman.py
Today's weather: who knows

python weatherman.py
Today's weather: rain

在兩個不同的地方 → 使用 import

  • 匯入主程式 weatherman.py(模組 report的主程式)
import report
  • 在模組檔 report.py 裡面,get_description()函式 → 由「Python 標準隨機模組」匯入「choice函式」
from random import choice

以兩種不同的方式 → 使用 imports

  • 主程式 → 呼叫 import report,接著執行 report.get_description()
  • report.py 裡面 → get_decription() 呼叫 from random import choice,接著執行 choice(possibilities)

【案例二】

  1. 一個函式裡面,知道這裡沒有其他叫做「choice」的東西
  2. 直接從「random 模組(Python 內建標準模組庫)」匯入「choice() 函式」
  3. 採取下列方式來「編寫函式」→ 它會「回傳隨機結果」

「函式內」匯入模組 v.s. 「函式外」匯入模組

  • 「函式內」匯入模組:只會在有限的範圍內使用它,就可在裡面匯入
  • 「函式外」匯入模組:
    • 要匯入的程式會在許多地方用到,就必須考慮在函式外面匯入它
    • 有些人喜歡將所有的 import 放在檔案的開頭,清楚地展示程式間的關係
  • 這兩種方式都是可行的

「函式內」匯入模組

  1. 如同許多其他程式部分,請挑選你最容易理解的方式
  2. 以模組來指定名稱(模組名稱.函式名稱)比較安全,但需要打較多字
  3. 這些 get_description()範例展示該匯入什麼,但沒有展示從哪裡匯入,它們都在函式裡呼叫 import
def get_description():
    import 模組名稱
    串列名稱 = ['字串1', '字串2', '字串3', '字串4', '字串5', '字串6']
    return 模組名稱.函式名稱(串列名稱)
>>> def get_description():
    import random
    possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']
    return random.choice(possibilities)      # 以模組來指定名稱(random.choice)比較安全,但需要打較多字

>>> get_description()
'rain'
>>> get_description()
'snow'

「函式外」匯入模組

  1. 以上這些 get_description()範例展示該匯入什麼,但沒有展示從哪裡匯入,它們都在函式裡呼叫 import
  2. 也可以在「函式外」匯入「模組」
>>> import 模組名稱
>>> def get_description():
        串列名稱 = ['字串1', '字串2', '字串3', '字串4', '字串5', '字串6']
        return 模組名稱.函式名稱(串列名稱)
>>> import random                             # 也可以在函式外面匯入 random
>>> def get_description():
    possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']
    return random.choice(possibilities)

>>> get_description()
'snow'
>>> get_description()
'rain'

用其他的名稱來匯入模組

  1. 在 weatherman.py 主程式中,呼叫了 import report
  2. 如果有「其他的模組」使用「相同的名稱」,或想要使用「有助記憶」或「簡短名稱」時,該怎麼做?可以用別名來匯入
import 模組名稱 as 別名
description = 別名.get_description()
print("文字:", description)
import report as wr
description = wr.get_description()
print("Today's weather:", description)

只匯入模組內你想要的東西

在 Python 中,可以匯入模組的一或多個部分。每一個部分都可以「保留它原本名稱」,也可以給它一個「別名」

【範例】

# 匯入模組的 get_description()
from 模組名稱 import get_description
description = get_description()
print("文字:", description)

# 用別名來匯入
from 模組名稱 import get_description as 別名
description = 別名()
print("文字:", description)
# 首先,用原始名稱來匯入 report 模組的 get_description()
from report import get_description
description = get_description()
print("Today's weather:", description)

#接著,用 do_it 來匯入它
from report import get_description as do_it
description = do_it()
print("Today's weather:", description)

模組搜尋路徑

  • Python 會去哪裡尋找要匯入的檔案?
    • 使用「sys 標準模組」的「path 變數」內的一串「目錄名稱串列」,以及「ZIP 保存檔案(archive files)」
    • 可以存取與修改這個串列
  • 以下是在自己的 Mac 上,Python 3.6 的 sys.path 的值:
>>> import sys
>>> for place in sys.path:
    print(place)

    # 前面一開始的空白是一個空字串'',代表目前的目錄

/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
  • 如果 sys.path 的第一行是 ' ',當試著匯入時,Python 會先查看目前的目錄 → 例如:import report 會尋找 report.py
  • 使用第一個找到的對象 → 例如:如果定義一個名叫 random 的模組,而且它的「搜尋路徑的位置」在「標準程式庫」之前,你就無法存取標準程式庫的 random 了

results matching ""

    No results matching ""