---
# System prepended metadata

title: 最小的 Python 專案範例
tags: [project, minimal, editable mode, Python, pyproject.toml]

---

最小的 Python 專案範例
===
###### tags: `Python`
###### tags: `Python`, `minimal`, `project`, `pyproject.toml`, `editable mode`

<br>

[TOC]

<br>

## 討論

### 建立一個最小的 Python 專案範例
- ### gpt-5 (2025/08/24)
    好的 👍 我幫你建立一個最小的 Python 專案範例，可以打包成安裝檔。這個範例會展示 **最基本的專案結構**、**程式碼**、**打包設定**，並且能夠產生可安裝的 `.whl` 或 `.tar.gz` 檔。

    ---

    ### 1. 專案結構

    ```
    myproject/
    ├── pyproject.toml
    ├── README.md
    └── myproject/
        ├── __init__.py
        └── main.py
    ```

    ---

    ### 2. 範例程式碼

    #### `myproject/main.py`

    ```python
    def hello():
        print("Hello, world!")
    ```

    #### `myproject/__init__.py`

    ```python
    from .main import hello
    ```
    - **備註**：經實測，非必要設定

    ---

    ### 3. 打包設定 (`pyproject.toml`)

    這裡使用 `setuptools` 來做最小的打包設定：

    ```toml=
    [build-system]
    requires = ["setuptools>=61.0"]
    build-backend = "setuptools.build_meta"

    [project]
    name = "myproject"
    version = "0.1.0"
    description = "A minimal Python project example"
    authors = [
        {name = "Your Name", email = "you@example.com"}
    ]
    readme = "README.md"
    requires-python = ">=3.8"

    [project.scripts]
    myhello = "myproject.main:hello"
    ```
    - `[project.scripts]`
        這裡的 `myhello` 會產生一個可執行的命令，安裝後在終端可以直接執行 `myhello`，它會印出 `Hello, world!`。
    - **備註**：
        - 若要產生 whl 檔，只需 `pyproject.toml` 空檔案就可以，內容可不用填寫

    ---

    ### 4. 產生安裝檔

    在專案根目錄下執行：

    ```bash
    # 需要安裝 build 模組
    python -m pip install --upgrade build
    python -m build
    ```

    產出結果會在 `dist/` 目錄，例如：

    ```
    dist/
    ├── myproject-0.1.0-py3-none-any.whl
    └── myproject-0.1.0.tar.gz
    ```

    ---

    ### 5. 測試安裝

    ```bash
    pip install dist/myproject-0.1.0-py3-none-any.whl
    ```

    安裝完成後可以執行：

    ```bash
    myhello
    ```

    輸出：

    ```
    Hello, world!
    ```

<br>

### 改了程式碼就能立刻生效，要如何做？
- ### gpt-5 (2025/08/24)
    要做到 **「改了程式碼就能立刻生效」**，一般就是讓專案以「**開發模式 (editable mode)**」安裝，而不是打包成 `.whl` 或 `.tar.gz` 再安裝。這樣 Python 會直接連結到你的原始碼資料夾，每次修改程式都能即時生效。

    ---

    #### 方法 1：使用 pip 的開發模式

    在專案根目錄執行：

    ```bash
    pip install -e .
    ```

    其中 `-e` 代表 *editable mode*。

    這樣安裝後，Python 其實會在 site-packages 裡建立一個連結指向你的專案目錄，而不是複製檔案。因此你修改 `myproject/main.py` 之後，不需要重新安裝，直接執行：

    ```bash
    myhello
    ```

    會立刻反映最新程式碼。

    ---

    #### 方法 2：使用 `venv` + 執行專案原始碼

    有時候你只是自己開發，不想一直重新安裝，可以直接在專案根目錄用虛擬環境來跑：

    ```bash
    python -m venv venv
    source venv/bin/activate   # Linux/Mac
    venv\Scripts\activate      # Windows
    ```

    然後在專案根目錄跑：

    ```bash
    python -m myproject.main
    ```

    這樣也是隨改隨用。

    ---

    #### 方法 3：結合 `setuptools` 的 `develop`

    如果你用的是 `setuptools`，也可以用：

    ```bash
    python setup.py develop
    ```

    它和 `pip install -e .` 的效果一樣，只是比較舊的寫法。

    ---

    ✅ **建議做法**
    在現代 Python 專案裡，最常見就是 `pip install -e .`。
    這樣你同時可以：

    * 在開發中隨改隨用
    * 測試安裝時的 entry point (`myhello`)
    * 不需要每次修改都重新 build/安裝

    ---

    要不要我幫你把之前的範例專案 (`pyproject.toml`) 修改成適合「開發模式」的設定，直接 `pip install -e .` 就能用？

<br>

### ERROR: File "setup.py" or "setup.cfg" not found.
- ### Question
    ```
    $ pip install -e .
    ERROR: File "setup.py" or "setup.cfg" not found. Directory cannot be installed in editable mode: /mnt/c/__workplace__/python-test/myproject
    (A "pyproject.toml" file was found, but editable mode currently requires a setuptools-based build.)
    ```
- ### gpt-5 (2025/08/24)
    這個錯誤訊息說明得很清楚：

    > 找到了 `pyproject.toml`，但目前 **editable mode (`-e`)** 需要 **setuptools 型的 build**，否則無法安裝。

    也就是說，你的 `pyproject.toml` 雖然存在，但 pip 還是需要知道這是一個「支援 editable」的 setuptools 專案。解法有兩種：

    ---

    ### ✅ 解法 1：在 `pyproject.toml` 加上 `[tool.setuptools]`

    請在 `pyproject.toml` 末尾補上這段（明確告訴 pip 用 setuptools 管理套件）：

    ```toml
    [tool.setuptools]
    packages = ["myproject"]
    ```

    完整範例如下：

    ```toml=
    [build-system]
    requires = ["setuptools>=61.0"]
    build-backend = "setuptools.build_meta"

    [project]
    name = "myproject"
    version = "0.1.0"
    description = "A minimal Python project example"
    authors = [
        {name = "Your Name", email = "you@example.com"}
    ]
    readme = "README.md"
    requires-python = ">=3.8"

    # 安裝後會產生一個可執行指令 `myhello`
    [project.scripts]
    myhello = "myproject.main:hello"

    # 明確告訴 setuptools 這個專案的套件
    [tool.setuptools]
    packages = ["myproject"]
    ```

    然後再跑：

    ```bash
    pip install -e .
    ```

    就可以成功了 🎉

    ---

    ### ✅ 解法 2：補一個 `setup.cfg`（比較舊但穩）

    如果你不想改 `pyproject.toml`，也可以直接在專案根目錄加一個 **setup.cfg**：

    ```ini
    [metadata]
    name = myproject
    version = 0.1.0

    [options]
    packages = find:
    python_requires = >=3.8
    ```

    然後再執行：

    ```bash
    pip install -e .
    ```

    一樣能隨改隨用。

    ---

    📌 **建議做法**：因為你已經有 `pyproject.toml`，我會建議用 **解法 1**。
    這樣就是純粹的 **PEP 621 + setuptools** 方案，最乾淨也最符合新標準。

<br>

{%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}
