Home
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

4

Local AI

--

Uedu Code

--

Taipei AQI 46 · Taichung AQI 76 · Tainan AQI 67 · Kaohsiung AQI 64
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 16

模組設計與使用

import、from ... import 與 __name__
Interaction實作導覽 20 minute(s)

Learning Objectives

  • 定義模組(module):一個 .py 檔就是一個模組
  • 使用模組:import、import ... as、from ... import
  • 用 dir() 查看模組裡定義了哪些名稱
  • __name__ 內建變數的用法:分辨「直接執行」與「被匯入」

為什麼需要模組

程式越寫越長,全部塞在同一個檔案裡會很難找、也很難重複使用。模組(module) 就是把相關的函數、類別與變數放在同一個 .py 檔,其他程式要用時再匯入。

  • 模組名稱=檔名去掉 .py:support.py 就是 support 模組
  • 模組可以定義函數、類別、變數,也可以有直接執行的程式碼
  • 你已經用過不少模組:math、random 都是 Python 標準函式庫的模組

本課的範例會在工作目錄先放好 support.py、bmi.py 這些模組檔,你可以在「檔案」分頁看到它們的內容。 動畫播放時,記憶體區的框架標題如果標示 support.py,代表那一步正在執行模組裡的程式。

import:匯入整個模組

import support 會在模組搜尋路徑找到 support.py,從頭執行一次,然後在主程式建立一個名稱 support 指向這個模組。注意:第二次 import support 時,執行箭頭有沒有再跑進 support.py?

import ... as 與 from ... import

import support as sp 幫模組取別名;from support import show_name 則把 show_name 這個名稱直接放進主程式,呼叫時不必加前綴。看右邊主程式的變數:sp 指向模組,show_name 指向函數。最後自己定義同名函數時,show_name 指向的東西換掉了。

三種匯入寫法比較

寫法 之後怎麼用 適合的情況
import support support.show_name('Rose') 一般情況;看得出名稱來自哪個模組
import support as sp sp.show_name('Rose') 模組名稱很長,例如 import numpy as np
from support import show_name show_name('Rose') 只需要模組裡的少數幾個名稱
from support import * show_name('Rose') 方便但要小心:所有名稱都倒進來,容易蓋掉同名的變數

不論 import 幾次、用哪一種寫法,同一個模組只會載入一次;之後的 import 只是取用已經載入的模組。

dir():模組裡有哪些名稱

dir(模組) 傳回模組內定義的所有名稱,是排序過的串列(list)。__ 開頭結尾的是 Python 自動加的系統名稱,例如 __name__、__doc__。

想一想:匯入

1.

下面的程式會印出什麼?

from math import sqrt
print(sqrt(16))
2.

下面的程式會印出什麼?

from math import pi
pi = 3
import math
print(pi, math.pi)
3.

import numpy as np 之後,下面哪一種寫法是正確的?

第 1 次作答

__name__:我是被直接執行,還是被匯入?

每個模組都有一個內建變數 __name__,它的值有兩種可能:

情況 __name__ 的值
直接執行這個檔案(python bmi.py) '__main__'
被其他程式 import 模組名稱,例如 'bmi'

所以模組常在最後寫:

if __name__ == '__main__':
    # 只有直接執行這個檔案時才會跑(例如測試、示範)
    main()

這樣同一個檔案「自己執行時」可以當成小程式,「被匯入時」只提供函數,不會突然跳出 input() 問身高體重。 另外,__file__ 代表模組的檔名。下面兩個動畫用同一份 bmi.py,一次被匯入、一次直接執行。

被匯入時:if 區塊不會執行

主程式 from bmi import BMI。注意 bmi.py 印出的 __name__ 是什麼,以及執行箭頭在 if __name__ == '__main__': 之後跳到哪裡。

直接執行時:if 區塊會執行

同樣的程式,這次是「直接執行」:它就是主程式。下方可以改 input() 讀到的身高與體重再跑一次。

在終端機:直接執行與匯入、模組搜尋路徑

同一個資料夾 lab 裡有 bmi.py(上面那份)和 main.py(from bmi import BMI 的主程式)。跟著步驟看看在終端機執行時會發生什麼事。

  1. 1

    直接執行 bmi.py

    python 檔名 執行的檔案就是主程式,__name__ 是 '__main__',所以會問身高體重。

  2. 2

    執行 main.py,由它匯入 bmi

    這次 bmi.py 是被匯入的,__name__ 是 'bmi',輸入身高體重的程式不會執行。

  3. 3

    模組搜尋路徑 sys.path

    import bmi 時,Python 依序在下列位置找 bmi.py,找到第一個就停:

    1. 主程式所在的目錄(用 python -c 或互動模式時是目前目錄,顯示為空字串)
    2. 環境變數 PYTHONPATH 設定的路徑
    3. 預設路徑:標準函式庫、site-packages(pip 安裝的第三方套件放在這裡)

    這些路徑存在 sys 模組的 path 串列裡。下面的路徑只是範例,每台電腦都不同。

  4. 4

    找不到模組時

    換到上一層目錄再匯入 bmi:搜尋路徑裡沒有 bmi.py,就會出現 ModuleNotFoundError。解法是回到模組所在的目錄執行,或把模組放在搜尋路徑裡。

  5. 5

    __pycache__ 資料夾

    回到原來的目錄,會發現多了 __pycache__:Python 把匯入過的模組編譯成 .pyc 快取,下次匯入比較快。它是自動產生的,不需要手動管理,也不必放進版本控制。(Windows 的命令提示字元用 dir /b 代替 ls)

這段導覽完成了

想一想:__name__

1.

main.py 裡寫了 import bmi。執行 python main.py 時,bmi.py 裡的 __name__ 是什麼?

2.

下面的程式直接執行時會印出什麼?

def hello():
    return "hi"

if __name__ == "__main__":
    print(hello(), end=" ")
print("end")
第 1 次作答

實作:讓 bmi 模組可以自己測試

下面是 bmi 模組。請在檔案最後加上 if __name__ == '__main__': 區塊,在區塊裡呼叫 BMI(67, 175),並用 {:.2f} 印出 175cm, 67kg, BMI=21.88。這樣直接執行時會印出測試結果,被匯入時則不會。

你的輸出
預期輸出

重點精華回顧

  • 模組=一個 .py 檔,模組名稱就是檔名;裡面可以有函數、類別、變數與可執行的程式。
  • import 模組 用「模組.名稱」存取;import 模組 as 別名 簡化名稱;from 模組 import 名稱 把名稱直接放進目前的命名空間。
  • from 模組 import * 很方便,但同名的名稱會互相覆蓋,要小心使用。
  • 同一個模組只會載入一次;第一次匯入時,模組最上層的程式會執行一次。
  • dir(模組) 傳回模組內所有名稱的排序串列。
  • 直接執行時 __name__ == '__main__';被匯入時 __name__ 是模組名稱。用 if __name__ == '__main__': 放「只在直接執行時才跑」的程式。
  • 匯入時依 sys.path 的順序搜尋模組:主程式所在目錄、PYTHONPATH、預設路徑。
這一課完成了!
Next lesson:例外處理
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。