Featured image of post 不知道如何建立自己的Python套件?快讓我一步步教你

不知道如何建立自己的Python套件?快讓我一步步教你

讓你在10分鐘內建構出專屬於自己的Python套件

前言

市面上,教讀者如何如何撰寫Python程式的書籍很多。關於如何進行數據分析或是深度學習的程式撰寫,更是不勝枚舉。但對於如何將自己所撰寫的程式進行打包、分享,並讓其他人可以安裝使用的教學,卻不是非常多。在本文中,將會介紹如何建構簡易的Python程式,並示範如何將其打包成容易分享的方式。

前置準備

建立資料夾

首先,需要先準備一個資料夾作為套件的根目錄。在Linux系統中,可以利用以下指令建立一個資料夾:

1
mkdir build_your_package_demo

這樣,就會在現有的目錄中,建立一個名為build_your_package_demo的資料夾。

建立必要檔案

要建立一個Python套件,在套件的根目錄中有幾個檔案是必要的。以下是必要的檔案列表:

  • setup.py: 用以描述套件資訊以及相關建構的設定。
  • LICENSE:用以描述套件授權條款。
  • README.md:用來提供使用者關於本套件的相關訊息。

我們可以用以下指令快速建立所需要的檔案:

1
2
3
4
cd build_your_package_demo/
touch setup.py
touch LICENSE
touch README.md

此時,套件的資料夾之中應該會有以下結構:

1
2
3
4
5
6
build_your_package_demo/
├── LICENSE
├── README.md
└── setup.py

0 directories, 3 files

除了上述的三個必要檔案,我們還要在build_your_package_demo的資料夾下面建立一個屬於套件程式碼的資料夾。假設我們將要建立一個名為Bifrost的套件,那我們需要在build_your_package_demo的資料夾中建立一個名為Bifrost的資料夾:

1
mkdir Bifrost

為了讓Python在建立套件時,能夠解析到Bifrost這個資料夾,我們需要在Bifrost資料夾中建立一個名為__init__.py的檔案。我們可以用以下指令建立__init__.py

1
touch Bifrost/__init__.py

__init__.py檔案可以是空的,也可以用來建立一些關聯性,這邊先不去在這個檔案著墨太多。

為檔案填入內容

LICENSE

常見的軟體授權條款有:

  • MIT授權
  • GPL授權
  • LGPL授權
  • BSD授權
  • APACHE授權

在此我們就不一一介紹,僅用一張表格來表達各個授權的差異。詳見下表:

條款GPLLGPLBSDAPACHEMIT
公開原始碼
以相同方式授權
標注修改部份
必須包含智慧財產權標記
必須包含授權條款

表格來源:為Medium文章之重製版本。

在此我們可以使用MIT授權條款作為軟體授權使用。只要將以下內容加入LICENSE檔案中即可:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Copyright (c) 2022 <put your name here>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

README.md

README.md是一個基於Markdown語法的介紹文件。編寫此文件的目的在於提供給使用者的「說明書」。README文件的主要目的為讓使用者了解以下資訊:

  • 這是什麽套件
  • 這套件能提供什麽功能
  • 該如何使用這個套件
  • 使用範例
  • 授權條款

為求簡單,我們可以先只用一行描述來構成我們的README.md檔案。輸入以下指令可以將一段文字加入到README.md之中:

1
echo "This is a demo for building your own python package." > README.md

:::info 有興趣了解如何撰寫一篇好的README文件,可以參考這篇文章 :::

setup.py

setup.py是一個在建立套件時,最重要的一個檔案。其內容跟以下資訊有關:

  • 作者資訊
  • 版本資訊
  • 套件名稱
  • 套件描述
  • 套件所需的相依套件
  • …….

我們可以依照下方所提供的內容來編寫setup.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="Bifrost",
    version="0.0.1",
    author="<your name>",
    author_email="<your email>",
    description="A demo project about how to build your own python package.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
    install_requires=[
        'numpy>=1'
    ]
)

建構套件程式碼

接下來,我們可以開始為Bifrost套件加入程式碼了。在開始之前,我們先回顧一下現有的檔案架構。在現有的資料夾下,我們有三個檔案以及一個目錄,如下方所示:

1
2
3
4
5
6
7
8
build_your_package_demo/
├── Bifrost
│   └── __init__.py
├── LICENSE
├── README.md
└── setup.py

1 directory, 4 files

假設Bifrost套件將有一個子模組,名為functuon,儲存在function.py之中。我們同樣可以使用touch指令建立function.py

1
touch Bifrost/function.py

此時,我們的套件資料夾架構將如下圖所示:

1
2
3
4
5
6
7
8
9
build_your_package_demo/
├── Bifrost
│   ├── __init__.py
│   └── function.py
├── LICENSE
├── README.md
└── setup.py

1 directory, 5 files

function.py

假設我們的核心函式將會在呼叫時回應「你好!」。我們可以在Bifrost/function.py中來實作這一項功能:

1
2
def greeting():
    print("你好!")

__init__.py

在先前,我們暫時將__init__.py留白,並未填入內容。但為了在建構套件時,我們的三個子模組能被正確的辨識,我們需要在__init__.py之中加入以下幾行文字:

1
from . import function

打包套件

安裝必要套件

在打包之前,我們需要先安裝必要的套件。必要的套件列表如下:

  • setuptools
  • wheel

這兩個套件都可以透過pip指令安裝。安裝指令如下:

1
python3 -m pip install setuptools wheel build

接下來,我們可以透過幾種方式來打包、安裝我們所建立的套件:

  1. 直接安裝
  2. 打包成tar.gz檔案
  3. 打包成wheel檔案

直接安裝

我們可以透過直接在build_your_package_demo目錄下執行以下指令來將套件安裝到Python函式庫之中:

1
python3 -m pip install -e .

打包成tar.gz檔案

pip指令的使用上,除了直接利用-e選項來直接將開發中的程式碼進行安裝以外,還能透過tar.gz以及wheel檔案來進行安裝。我們可以透過在build_your_package_demo目錄下執行以下指令來將套件打包成tar.gz檔案:

1
python3 -m build --sdist

這個指令會在目前的資料夾之下新增一個dist/資料夾,並在其中新增一個Bifrost-0.0.1.tar.gz壓縮檔案。我們可以夠過pip指令來將打包好的套件安裝到函式庫之中。

1
python3 -m pip install dist/Bifrost-0.0.1.tar.gz

打包成wheel檔案

在上一小節中,我們示範了如何將套件打包成tar.gz並進行安裝。而我們也可以選擇將套件打包成wheel檔案並進行安裝。與上一小節所使用的指令相似,只需要將sdist參數換成bdist_wheel即可打包成wheel檔案。

1
python3 setup.py build --wheel

這樣一來,我們將會在dist/資料夾下得到一個名為Bifrost-0.0.1-py3-none-any.whl的檔案。我們同樣可以利用與上一節相同的pip指令進行安裝。

1
python3 -m pip install dist/Bifrost-0.0.1-py3-none-any.whl

對於setup.py以及setuptools的詳細介紹,可以參考本篇文章。 也可以參考官方的教學

測試

在成功安裝Python套件之後,我們可以透過pip指令加上show參數來確認我們安裝的套件。執行以下指令即可得到關於Bifrost套件的相關資訊。

1
pip3 show Bifrost

指令將會回應以下訊息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Name: Bifrost
Version: 0.0.1
Summary: A demo project about how to build your own python package.
Home-page:
Author: <your name>
Author-email: <your email>
License:
Location: /Users/user/Library/Python/3.9/lib/python/site-packages
Requires: numpy
Required-by:

我們也可以嘗試在互動模式下導入Bifrost模組並進行操作。

  1. 進入互動模式

    可以透過以下指令進入互動模式:

1
python3
  1. 導入Bifrost套件 在互動模式中導入Bifrost套件:
1
import Bifrost
  1. 查看套件架構 利用dir()函式查看Bifrost套件架構:
1
dir(Bifrost)

dir()函式將會發送以下回應:

1
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'function']

也可以查看Bifrost套件中的function子套件架構:

1
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'greeting']
  1. 嘗試執行套建中的函式

可以嘗試執行Bifrost.utilsprint_numpy_version函式來確認套件是否可以正常運作。

1
2
>>> Bifrost.function.greeting()
你好!

經過以上測試,可以確認套件已經正確的被安裝了。

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy