Featured image of post Python 系列: 模組(module)與套件(package)撰寫

Python 系列: 模組(module)與套件(package)撰寫

紀錄一些關於python module 和 package 的學習筆記,希望以後能常用上。

python module

模組化 (modularization): 將常會使用的函式(或物件)單獨寫成一份 script 後,再利用 (from) import 方式呼叫,可方便管理函式,不用從單一script追溯以增加效率

python package

套件 (package) 指的是 包含相關的程式檔案的資料夾結構類似普渡的樂式大禮包只要引用套件就可任意使用內部模組,一般套件名稱等於資料夾名稱

將模組打包成套件的步驟:

  1. 建立一個資料夾,並命名為套件名稱
  2. 建立 __init__.py ,python要求資料夾必須包含此檔案,才可以被識別為套件
  3. 將相關模組script放進來
  4. 在新的script以 import 或是 from ... imoprt 來引入套件與模組使用,詳細差異可看下面實例會更清楚 **還有一種引入為from .. import* 但容易在模組名稱相同時發生衝突,就不給例子了

實例

今天簡單寫一個名為 helpwork 的套件,內含 tellname.pytelltime.py 兩份script分別定義函式:

1
2
3
4
5
6
7
## telltime.py

import datetime

def telltime():
    now = datetime.datetime.now()
    print(now)
1
2
3
## tellname.py
def tellname(name):
    print('welcome {}'.format(name))

資料夾結構為:

開啟新 python script 測試能否引入:

  • 使用 from ${package_name} import ${module_name},引用函式要 ${module_name}.${func_name}()
1
2
3
4
from helpwork import tellname, telltime

telltime.telltime() 
tellname.tellname('Amy')

成功執行函式,並印出

1
2
2024-08-xx xx:xx:xx.xxxxx
welcome Amy
  • 使用 import ${package_name},以${package_name}.${module_name}.${func_name}()引用函式 注意: 若只給到 ${package_name}.${module_name} 會報錯 TypeError: 'module' object is not callable
1
2
3
4
import helpwork

helpwork.telltime.telltime()
helpwork.tellname.tellname('Cindy')

成功執行函式,並印出

1
2
2024-08-xx xx:xx:xx.xxxxx
welcome Cindy

這時會看到原本 helpwork資料夾下多了 pycache 資料夾

套件研究: openpyxl

之前介紹過操作 xlsx 檔的實用套件 openpyxl,當時寫的引入方式為

1
2
import openpyxl
from openpyxl import workbook, worksheet

這裡的 workbook, workshet 都屬於模組,在官方github 可看到套件的資料夾結構:

補充說明,若想區隔模組或避免同名函式混用出錯,可以將模組單獨建一個資料夾並放置函式script以及一份__init__.py;如上圖可見 workbook 模組資料夾下、有一份__init__.py 和放函示跟物件的 workbook.py

因此想建立 workbook/workbook.py 裡面定義的 Workbook 物件,以下兩種方式都能做到:

1
2
3
4
### method1
from openpyxl import workbook

wb = workbook.Workbook()
1
2
3
4
5
### method2

from openpyxl import Workbook

wb = Workbook()

測試workbook.py 內定義的其中一個函式 sheetnames

1
2
3
wb = workbook.Workbook()
wb.create_sheet('New_created')
print(wb.sheetnames)

成功印出新建的sheet跟預設sheet

1
['Sheet', 'New_created']

(進階) 打包套件與推送

若想在不同平台使用同個套件,可以打包推送再安裝回本地使用 建議可先將 package code 推送至 Github,須包含以下基本內容:

1
2
3
4
5
6
${package_name}(.git那層)
${package_name}/
├── README.md
├── module/
│   └── __init__.py
└── setup.py

其中 setup.py 紀錄套件相關的資訊,一般會引用兩種套件協助打包: distutilssetuptools (後者較常用) 以 setup() 提供套件相關資訊

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
## pip install setuptools
from setuptools import setup

setup(
name='helpwork',
version='v0.0.1',
description='simple script to test',
author='px',
author_email='hello123@gmail.com'
...
)

打包完成,可以選擇:

  • 安裝在環境 python3 setup.py install
  • 打包 python3 setup.py sdist / bdist_{egg;wheel} 一個式 source code 一個式打包 metadata (出來的格式類似.zip)
  • 推送到TestPyPI 或 PyPI (需要申請帳號) python3 setup.py sdist upload -r pypi

關於打包的更多介紹可以看這個網站: https://fuchencong.com/2021/12/07/python-package/ 由於沒有實際完成這步,未來有做會再來更新~

References

https://hackmd.io/@celineyeh/SyJSK8AXB https://medium.com/pyladies-taiwan/python-%E7%9A%84-import-%E9%99%B7%E9%98%B1-3538e74f57e3 https://www.learncodewithmike.com/2020/01/python-module-and-package.html https://medium.com/seaniap/python-%E6%A8%A1%E7%B5%84%E8%88%87%E5%A5%97%E4%BB%B6-8aa890eda31a https://setuptools.pypa.io/en/latest/setuptools.html https://fuchencong.com/2021/12/07/python-package/

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus