1. 前言
Python 套件的重要性
Python 的套件是一種將多個模組組合在一起的結構,能夠讓程式碼的重複利用與管理變得更加簡單。特別是在大型專案中,透過適當地設計套件架構,可以大幅提升程式碼的可讀性與維護性。
雖然 Python 生態系統中已經有許多實用的套件(函式庫)可供使用,但透過自行開發套件並應用於專案中,將能讓開發過程更加靈活。
本文的目的與概要
本篇文章將針對 Python 套件進行詳細說明,內容包括以下幾點:
- 套件的基本概念與結構
- 如何建立自製套件
- 如何匯入套件
- 使用
pip
進行套件管理 - 將套件發佈至 PyPI(Python Package Index)的流程
- 常見錯誤與對應解法(FAQ)
閱讀本指南後,您將能系統性地理解 Python 套件的運作方式,並實際應用在開發中。
適合的讀者對象
本篇文章適合以下讀者:
- 已具備 Python 基礎語法知識,並曾撰寫簡單腳本或函式者
- 希望整理專案架構、撰寫易於重複利用程式碼的開發者
- 想要建立自己的套件並發佈到 PyPI 的人
本指南旨在協助這些讀者更加深入理解 Python 套件,並提供實用的開發知識。
2. 什麼是 Python 套件?
套件與模組的差異
在 Python 中,為了讓程式碼結構更清晰、便於重複使用,引入了「模組」與「套件」的概念。
- 模組(Module)
指的是單一的 Python 腳本(.py
檔案)。例如,以下的 Python 檔案就是一個模組:
# sample_module.py
def greet():
return "Hello, Python!"
- 套件(Package)
是由多個模組組成的資料夾(目錄),通常會包含一個__init__.py
檔案。透過套件可以更有組織地管理多個模組。
mypackage/
├── __init__.py
├── module1.py
├── module2.py
與函式庫的差異
「函式庫(Library)」這個詞也經常被使用,它是比模組或套件更廣泛的概念。
函式庫通常是由多個套件所組成,用來提供特定功能的工具集合。
術語 | 說明 |
---|---|
模組 | 單一的 Python 腳本檔(.py 檔案) |
套件 | 包含多個模組的目錄結構 |
函式庫 | 由多個套件所組成的軟體集合 |
例如,requests
或 numpy
是套件,而 SciPy
或 Django
則是結合多個套件的函式庫。
__init__.py
的角色
在套件目錄中,__init__.py
是一個特殊的檔案,它的存在讓 Python 能夠將該資料夾視為套件。
__init__.py
的基本用法
雖然 __init__.py
可以是空的,但你也可以在裡面定義一些初始化設定或匯出套件中的主要函式,例如:
# mypackage/__init__.py
from .module1 import greet
def welcome():
return "Welcome to mypackage!"
透過上述設定,當從外部匯入 mypackage
套件時,就能直接使用 greet()
函式:
from mypackage import greet
print(greet()) # Hello, Python!
命名空間套件(Namespace Package)
從 Python 3.3 開始,即使沒有 __init__.py
,Python 也能辨識為套件,這種形式被稱為「命名空間套件(Namespace Package)」。不過,為了相容性與可讀性,大多數情況下仍建議保留 __init__.py
。
小結
- 模組 是單一
.py
檔案,而套件 是由多個模組組成的資料夾結構。 - 函式庫 是包含多個套件與模組的軟體集合。
__init__.py
是辨識套件的重要檔案,也可以用來定義初始化內容與匯出功能。- 從 Python 3.3 起可使用「命名空間套件」,但一般仍建議保留
__init__.py
。
3. 如何建立 Python 套件
基本的套件目錄結構
Python 套件需要遵循一定的目錄結構才能正常運作。以下是一個簡單的套件目錄範例:
mypackage/
├── __init__.py # 套件識別檔案
├── module1.py # 模組1
├── module2.py # 模組2
└── subpackage/ # 子套件
├── __init__.py
├── submodule1.py
└── submodule2.py
各個檔案的角色
mypackage/
:套件的根目錄__init__.py
:標示此資料夾為 Python 套件(Python 3.3 之後可以省略,但建議保留)module1.py
、module2.py
:套件中的模組檔案subpackage/
:子套件,內含其他模組
__init__.py
的建立與功能
__init__.py
檔案的作用是讓 Python 能夠識別該目錄為套件,並可以定義在匯入時執行的初始化邏輯。
簡單的 __init__.py
即使是空的 __init__.py
檔案,也能讓資料夾作為套件運作:
# mypackage/__init__.py
在 __init__.py
中加入初始化設定
以下是一個更實用的範例,示範如何在 __init__.py
中定義初始化邏輯與匯出功能:
# mypackage/__init__.py
from .module1 import greet
def welcome():
return "Welcome to mypackage!"
這樣設定後,在匯入套件時就能直接使用 greet()
函式:
from mypackage import greet
print(greet()) # "Hello, Python!"
建立模組與子套件
建立模組(module1.py
)
每個模組可以定義自己專屬的函式與類別。例如:
# mypackage/module1.py
def greet():
return "Hello, Python!"
建立子套件(subpackage/
)
若希望功能更細分,可以透過子套件進一步組織程式碼:
mypackage/
└── subpackage/
├── __init__.py
├── submodule1.py
└── submodule2.py
在子套件的 __init__.py
中定義函式,便於使用者匯入:
# mypackage/subpackage/__init__.py
from .submodule1 import sub_function
def subpackage_greeting():
return "Hello from subpackage!"
測試套件功能
要確認建立的套件是否正常運作,可以使用 Python 的互動式命令列進行測試:
- 移動到
mypackage
的上層目錄
cd path/to/your/package
- 啟動 Python 命令列
python
- 匯入套件並執行函式
import mypackage
print(mypackage.welcome()) # "Welcome to mypackage!"
小結
- Python 套件 是由資料夾與
__init__.py
組成的結構。 __init__.py
用於識別與初始化套件。- 透過模組與子套件的分層設計,可提升程式碼的可讀性與組織性。
- 建立後應在 Python 命令列中測試,確認功能是否正常。

4. 套件的匯入方式
匯入套件中的模組
使用 Python 套件時,通常會透過 import
陳述式進行匯入。假設有以下套件結構:
mypackage/
├── __init__.py
├── module1.py
├── module2.py
└── subpackage/
├── __init__.py
├── submodule1.py
直接匯入模組
假設 module1.py
中有定義一個 greet()
函式:
# mypackage/module1.py
def greet():
return "Hello from module1!"
若要使用這個函式,可以這樣匯入:
import mypackage.module1
print(mypackage.module1.greet()) # Hello from module1!
使用 from
進行簡潔匯入
若希望匯入語法更簡潔,可以使用 from
陳述式:
from mypackage.module1 import greet
print(greet()) # Hello from module1!
相對匯入與絕對匯入的差異
在 Python 中,匯入同一套件中的其他模組時,可以使用 相對匯入 或 絕對匯入 兩種方式。
絕對匯入(Absolute Import)
從專案的根目錄開始指定完整的模組路徑:
# mypackage/module2.py
from mypackage.module1 import greet
def call_greet():
return greet()
這種方式的好處是可讀性高,結構清晰。
相對匯入(Relative Import)
以當前模組所在位置為基準,使用 .
來參照其他模組:
# mypackage/module2.py
from .module1 import greet
def call_greet():
return greet()
使用 .
的數量可以表示層級,例如:
from .module1 import greet
→ 匯入同一層級的module1.py
from ..subpackage.submodule1 import some_function
→ 匯入上一層的subpackage/submodule1.py
中的some_function
相對匯入 vs 絕對匯入
類型 | 優點 | 缺點 |
---|---|---|
絕對匯入 | 可讀性高,結構明確 | 模組路徑較長,較繁瑣 |
相對匯入 | 語法簡潔,適合內部模組之間的互相匯入 | 從套件外部執行時可能出現錯誤(ImportError) |
由於相對匯入在從套件外部執行時容易出現錯誤,因此在大型專案中通常建議使用 絕對匯入。
利用 __init__.py
簡化匯入
可以在 __init__.py
中預先匯入常用函式或類別,讓外部使用時更加方便:
# mypackage/__init__.py
from .module1 import greet
這樣就能直接匯入套件並使用函式:
from mypackage import greet
print(greet()) # Hello from module1!
小結
- 匯入模組的方法 包含
import
與from ... import
兩種方式。 - 絕對匯入 結構清楚、可讀性高,但可能較冗長。
- 相對匯入 語法簡潔,但從套件外部執行時可能產生錯誤。
- 透過
__init__.py
簡化匯入 可以提升使用者體驗與套件易用性。
5. Python 套件的管理(活用 pip)
使用 pip
安裝與移除套件
在 Python 中,可以使用 pip
工具來輕鬆安裝外部函式庫。
透過 Python Package Index(PyPI) 官方套件庫下載並加入您的開發環境。
安裝套件
執行以下指令即可安裝指定套件:
pip install package_name
例如,若要安裝 requests
套件:
pip install requests
安裝完成後,即可在 Python 程式中透過 import
使用該套件:
import requests
response = requests.get("https://example.com")
print(response.status_code)
移除套件
若某套件不再需要,可使用 pip uninstall
將其移除:
pip uninstall package_name
例如,移除 requests
套件:
pip uninstall requests
執行後會出現確認提示,輸入 y
即可完成移除。
使用 pip freeze
和 requirements.txt
來管理環境
在專案開發中,為了讓團隊成員或部署環境能安裝一致的套件版本,通常會建立 requirements.txt
檔案。
列出當前安裝的套件
使用下列指令可列出目前環境中已安裝的所有套件及其版本:
pip freeze
輸出範例:
requests==2.26.0
numpy==1.21.2
pandas==1.3.3
將此清單輸出成檔案,可使用:
pip freeze > requirements.txt
從 requirements.txt
一次安裝所有套件
當在新環境中部署專案時,可透過下列指令安裝 requirements.txt
中列出的所有套件:
pip install -r requirements.txt
使用虛擬環境(venv)管理套件
為了讓不同專案使用獨立的套件環境,建議使用 虛擬環境(venv)。
這樣可以避免修改到系統全域的套件設定,提升穩定性與可維護性。
建立虛擬環境
進入專案資料夾,執行以下指令建立虛擬環境:
python -m venv myenv
這會建立名為 myenv/
的資料夾,裡面包含專屬的 Python 執行環境。
啟動虛擬環境
啟用虛擬環境的方法如下:
- Windows(PowerShell)
myenv\Scripts\Activate
- Mac / Linux
source myenv/bin/activate
啟動後,指令列前方會出現 (myenv)
,表示已進入虛擬環境。
在虛擬環境中管理套件
啟用虛擬環境後,可以像平常一樣使用 pip
安裝套件:
pip install flask
若要離開虛擬環境,可輸入:
deactivate
套件版本管理
查看已安裝套件的版本
使用下列指令可查看所有已安裝套件的版本:
pip list
若想查看特定套件的詳細資訊,可使用:
pip show package_name
範例:
pip show numpy
輸出內容可能如下:
Name: numpy
Version: 1.21.2
Summary: NumPy 是用於陣列運算的核心套件。
更新套件至最新版本
可使用以下指令將套件升級至最新版:
pip install --upgrade package_name
例如:
pip install --upgrade requests
若要一鍵升級所有套件(限 Linux / Mac 環境),可使用:
pip list --outdated | awk '{print $1}' | xargs pip install --upgrade
(※ 需要系統中安裝 awk
與 xargs
)
小結
pip install package_name
可安裝套件,pip uninstall
可移除。- 使用
pip freeze > requirements.txt
可記錄當前環境的所有套件,便於部署與版本控制。 - 透過虛擬環境(venv)為不同專案建立獨立環境,避免相互干擾。
- 使用
pip list
與pip install --upgrade
來管理與更新套件版本。
6. Python 套件的發佈方式
使用 pyproject.toml
設定套件資訊
在 Python 中建立並發佈套件時,建議使用 pyproject.toml
來進行套件的設定與建構。這個檔案用來定義套件的中繼資料與相依套件資訊。
pyproject.toml
的基本結構
在專案的根目錄建立 pyproject.toml
,並寫入以下內容:
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage"
version = "0.1.0"
description = "My Python package"
authors = [{ name = "Your Name", email = "your_email@example.com" }]
license = { text = "MIT" }
dependencies = ["requests", "numpy"]
設定好之後,即可使用標準工具進行套件的建構與發佈。
使用 setuptools
建立套件
若要將套件製作成可發佈的格式(如 sdist
或 wheel
),可使用 setuptools
來打包。
準備套件的目錄結構
請確保您的專案結構如下:
mypackage/
├── mypackage/
│ ├── __init__.py
│ ├── module1.py
│ ├── module2.py
├── pyproject.toml
├── README.md
└── LICENSE
mypackage/
(內層):實際的套件程式碼pyproject.toml
:套件設定檔README.md
:套件說明文件LICENSE
:授權資訊
建構套件
打開終端機並移動至專案根目錄,執行下列指令:
python -m build
執行後會在 dist/
目錄中產生 .tar.gz
(原始碼)與 .whl
(wheel)格式的檔案:
dist/
├── mypackage-0.1.0-py3-none-any.whl
├── mypackage-0.1.0.tar.gz
使用 twine
發佈至 PyPI
若要將套件發佈到 PyPI,可使用 twine
工具。
先在 TestPyPI 測試上傳
建議先將套件上傳至 TestPyPI 進行測試,避免直接發佈錯誤內容。
首先安裝 twine
:
pip install twine
接著將套件上傳至 TestPyPI:
python -m twine upload --repository testpypi dist/*
要從 TestPyPI 安裝套件時,可使用以下指令:
pip install --index-url https://test.pypi.org/simple/ mypackage
正式發佈到 PyPI
確認測試無誤後,即可將套件發佈至正式的 PyPI:
python -m twine upload dist/*
上傳後可以前往 https://pypi.org/ 搜尋您的套件並確認發佈成功。
從 PyPI 安裝套件
使用者可以透過以下指令安裝您發佈的套件:
pip install mypackage
小結
- 使用
pyproject.toml
來管理套件資訊與建構設定。 - 使用
python -m build
建立sdist
和whl
格式的發佈檔案。 - 使用
twine
先將套件發佈至 TestPyPI 測試,確認無誤後再上傳至正式 PyPI。 - 發佈後可透過
pip install
安裝並使用該套件。
7. 常見問題(FAQ)
__init__.py
是必需的嗎?
Q: 套件中一定要有 __init__.py
嗎?
A: 從 Python 3.3 開始,加入了 命名空間套件(Namespace Package) 的功能,即使沒有 __init__.py
也能被視為套件。
但在大多數開發實務中,仍然建議明確地建立 __init__.py
,以提高相容性與可讀性。
# mypackage/__init__.py
您也可以在這個檔案中撰寫初始化邏輯,或預先匯出常用功能以簡化匯入。
什麼是相對匯入與絕對匯入?
Q: 相對匯入與絕對匯入有什麼差別?
A: 在 Python 中,可以使用兩種方式來匯入模組:
- 絕對匯入(Absolute Import)
from mypackage.module1 import greet
- 清楚標示完整路徑,結構明確
- 可讀性高,不容易出錯
- 相對匯入(Relative Import)
from .module1 import greet
- 使用
.
表示與當前模組的相對位置 - 當從套件外執行時,可能會出現
ImportError
套件與模組的命名有規則嗎?
Q: Python 套件與模組命名有沒有建議規範?
A: 根據 PEP8(Python 官方風格指南),建議使用以下命名方式:
- 套件名稱:使用全小寫,簡短且具描述性
mypackage, utilities, datahandler
- 模組名稱:同樣建議使用小寫並避免冗長
module1, parser, reader
requirements.txt
有什麼用途?
Q: requirements.txt
是做什麼用的?
A: requirements.txt
是用來記錄專案所依賴的所有套件與版本。這可協助團隊開發時維持一致的環境設定,並方便在部署或重建時還原相同環境。
可使用下列指令自動產生:
pip freeze > requirements.txt
在其他環境中安裝時,可使用:
pip install -r requirements.txt
為什麼會出現 ModuleNotFoundError
或 ImportError
?
Q: 匯入時出現 ModuleNotFoundError
或 ImportError
,是什麼原因?該怎麼解決?
A: 這些錯誤通常是因為 Python 找不到模組或匯入路徑錯誤所導致。
錯誤類型 | 可能原因 | 解決方式 |
---|---|---|
ModuleNotFoundError | 模組尚未安裝 | 執行 pip install package_name |
ImportError | 匯入路徑錯誤 | 請改用絕對匯入方式測試 |
ModuleNotFoundError
的解法
- 確認套件是否已安裝:
pip list | grep package_name
- 若未安裝,請執行安裝:
pip install package_name
ImportError
的解法
- 嘗試使用絕對匯入:
from mypackage.module1 import greet
- 檢查執行目錄與模組路徑是否正確:
import sys
print(sys.path)
為什麼上傳到 PyPI 後無法 pip install
?
Q: 我已將套件上傳到 PyPI,但卻無法透過 pip install
安裝,為什麼?
A: 請檢查以下幾點:
- 確認上傳是否成功
twine check dist/*
- 確認使用正確的套件名稱
pip install mypackage
- 等待 PyPI 資料同步
- 上傳後可能需等待數分鐘才會顯示在 PyPI。
- 如果是上傳到 TestPyPI
- 請使用
--index-url
參數來指定來源:
pip install --index-url https://test.pypi.org/simple/ mypackage
小結
__init__.py
在 Python 3.3 之後雖非必需,但為相容性通常仍建議保留。- 絕對匯入 結構清晰、錯誤率低,推薦使用。
- 善用
requirements.txt
管理相依套件,提高環境一致性。 ModuleNotFoundError
與ImportError
通常可透過安裝套件與檢查匯入路徑解決。
8. 總結
Python 套件的基本概念
- 模組 是單一的
.py
檔案,套件 則是包含多個模組的資料夾結構。 - 函式庫 是由多個套件或模組所組成的軟體集合。
__init__.py
可用來識別套件並簡化匯入流程。
建立 Python 套件的方法
- 建立
mypackage/
資料夾並加入__init__.py
即可作為套件。 - 將功能分拆為多個模組,設計便於重複使用與維護的程式架構。
- 使用 絕對匯入 能讓模組關係更清楚,利於維護與除錯。
套件的管理方式
- 使用
pip install package_name
安裝套件,pip uninstall
可移除。 - 透過
pip freeze > requirements.txt
將相依套件記錄下來,方便部署與分享。 - 使用
python -m venv myenv
建立虛擬環境,為每個專案提供獨立的開發環境。
套件的發佈方式
- 使用
pyproject.toml
設定套件資訊與建構方式。 - 透過
python -m build
產生可發佈的檔案至dist/
目錄中。 - 先使用
twine
上傳至 TestPyPI 測試,確認正常後再發佈至 PyPI。 - 套件發佈後,可使用
pip install mypackage
進行安裝。
常見錯誤與對策
ModuleNotFoundError
通常是因為套件尚未安裝或路徑錯誤,可透過pip install
解決。ImportError
常見於相對匯入時,可改用絕對匯入方式避免問題。- 使用
pip list --outdated
可查詢過期套件,搭配pip install --upgrade
進行更新。
Python 套件管理的最佳實踐
- 遵循命名規範
- 套件與模組名稱建議使用簡潔的小寫字母,提升可讀性與一致性。
- 善用虛擬環境(venv)
- 避免影響全域環境,讓專案間相互獨立。
- 隨時維護
requirements.txt
- 能幫助團隊合作與部署過程更順利,減少環境差異造成的錯誤。
- 發佈前先在 TestPyPI 測試
- 能事先發現錯誤,確保上架品質與安裝體驗。
總結與進階學習方向
掌握 Python 套件的架構與管理方式後,您將能更有效率地開發與重用程式碼。
善用虛擬環境與標準化工具,將有助於打造更穩定與專業的開發流程。
接下來,您可以進一步學習以下主題,拓展技術深度:
- 進階套件開發技巧(如加入自訂指令、整合 C 擴充)
- 使用 CI/CD 自動化套件部署流程
- 結合 Docker 建立一致的開發與部署環境
希望本教學能幫助您更加理解 Python 套件的應用與發佈流程。
感謝您的閱讀!