<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Poetry on Tarragon</title><link>https://tarrragon.github.io/blog/tags/poetry/</link><description>Recent content in Poetry on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 21 Jan 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/poetry/index.xml" rel="self" type="application/rss+xml"/><item><title>案例：使用 Poetry 完整工作流</title><link>https://tarrragon.github.io/blog/python-advanced/07-packaging/case-studies/poetry-workflow/</link><pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/python-advanced/07-packaging/case-studies/poetry-workflow/</guid><description>&lt;p>本案例展示如何使用 Poetry 管理現代 Python 專案的完整生命週期，從專案建立到套件發布。&lt;/p>
&lt;h2 id="先備知識">先備知識&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/python-advanced/07-packaging/build-systems/" data-link-title="6.2 建構系統比較" data-link-desc="比較 setuptools、Poetry、Hatch 等建構系統">建構系統比較&lt;/a>&lt;/li>
&lt;li>Python 虛擬環境基礎&lt;/li>
&lt;li>套件相依性概念&lt;/li>
&lt;/ul>
&lt;h2 id="問題背景">問題背景&lt;/h2>
&lt;h3 id="現代專案的挑戰">現代專案的挑戰&lt;/h3>
&lt;p>傳統的 Python 專案管理面臨以下問題：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">傳統工作流程的痛點：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">├── 相依性管理
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">│ ├── requirements.txt 無法鎖定間接相依性
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">│ ├── pip freeze 產生的版本可能過於嚴格
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">│ └── 開發與生產環境相依性混在一起
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">├── 虛擬環境
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">│ ├── 需要手動建立和管理
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">│ ├── 不同專案的環境容易混淆
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">│ └── 缺乏與專案的關聯性
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">├── 建構與發布
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">│ ├── setup.py 設定複雜
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">│ ├── 發布流程需要多個工具
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">│ └── 版本管理不一致
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">└── 團隊協作
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> ├── 環境難以重現
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> ├── 「在我電腦上可以跑」問題
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl"> └── 新成員上手困難&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="為什麼選擇-poetry">為什麼選擇 Poetry？&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>特性&lt;/th>
 &lt;th>pip + venv&lt;/th>
 &lt;th>Poetry&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>相依性鎖定&lt;/td>
 &lt;td>手動（pip freeze）&lt;/td>
 &lt;td>自動（poetry.lock）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>間接相依性追蹤&lt;/td>
 &lt;td>無&lt;/td>
 &lt;td>完整追蹤&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>虛擬環境管理&lt;/td>
 &lt;td>手動&lt;/td>
 &lt;td>自動整合&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>建構系統&lt;/td>
 &lt;td>需要額外工具&lt;/td>
 &lt;td>內建&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>發布流程&lt;/td>
 &lt;td>需要 twine&lt;/td>
 &lt;td>內建&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>相依性群組&lt;/td>
 &lt;td>無原生支援&lt;/td>
 &lt;td>完整支援&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="解決方案">解決方案&lt;/h2>
&lt;h3 id="安裝-poetry">安裝 Poetry&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 官方推薦的安裝方式（獨立安裝）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">curl -sSL https://install.python-poetry.org &lt;span class="p">|&lt;/span> python3 -
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 或使用 pipx（推薦用於 CLI 工具）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">pipx install poetry
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="c1"># 確認安裝&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">poetry --version&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="設定-poetry">設定 Poetry&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 在專案目錄中建立虛擬環境（推薦）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">poetry config virtualenvs.in-project &lt;span class="nb">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 查看所有設定&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">poetry config --list&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="工作流一建立新專案">工作流一：建立新專案&lt;/h3>
&lt;h4 id="使用-poetry-new完整專案結構">使用 poetry new（完整專案結構）&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 建立新專案&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry new my-awesome-lib
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 產生的目錄結構&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">my-awesome-lib/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">├── pyproject.toml
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">├── README.md
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">├── my_awesome_lib/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">│ └── __init__.py
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">└── tests/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> └── __init__.py&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>




&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 使用 src layout（推薦用於函式庫）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry new --src my-awesome-lib
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 產生的目錄結構&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">my-awesome-lib/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">├── pyproject.toml
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">├── README.md
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">├── src/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">│ └── my_awesome_lib/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">│ └── __init__.py
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">└── tests/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> └── __init__.py&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="使用-poetry-init現有專案">使用 poetry init（現有專案）&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 在現有目錄初始化&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="nb">cd&lt;/span> existing-project
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">poetry init
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="c1"># 互動式問答&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="c1"># - Package name&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="c1"># - Version&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="c1"># - Description&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="c1"># - Author&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="c1"># - License&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="c1"># - Python version&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="c1"># - Dependencies&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="互動式初始化範例">互動式初始化範例&lt;/h5>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">This command will guide you through creating your pyproject.toml config.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">Package name [existing-project]: my-package
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">Version [0.1.0]: 1.0.0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">Description []: A useful Python package
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Author [Your Name &amp;lt;you@example.com&amp;gt;, n to skip]:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">License []: MIT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">Compatible Python versions [^3.10]: ^3.10
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">Would you like to define your main dependencies interactively? (yes/no) [yes]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">Search for package to add (or leave blank to continue): requests
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">...&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="工作流二管理相依性">工作流二：管理相依性&lt;/h3>
&lt;h4 id="新增相依性">新增相依性&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 新增生產相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry add requests
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">poetry add &lt;span class="s2">&amp;#34;httpx&amp;gt;=0.24&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="c1"># 新增開發相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">poetry add pytest --group dev
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">poetry add ruff mypy --group dev
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="c1"># 新增文件相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">poetry add mkdocs mkdocs-material --group docs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="c1"># 新增可選相依性（extras）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">poetry add pyyaml --optional&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="pyprojecttoml-的變化">pyproject.toml 的變化&lt;/h5>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="nx">python&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^3.10&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="nx">requests&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^2.31.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="nx">httpx&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;gt;=0.24&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dev&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="nx">pytest&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^8.0.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="nx">ruff&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^0.4.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="nx">mypy&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^1.10.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">docs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="nx">mkdocs&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^1.5.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="nx">mkdocs-material&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^9.5.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">extras&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="nx">yaml&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;pyyaml&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="移除相依性">移除相依性&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 移除生產相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">poetry remove requests
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 移除開發相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">poetry remove pytest --group dev&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="更新相依性">更新相依性&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 更新所有相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 更新特定套件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">poetry update requests
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="c1"># 檢視可更新的套件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">poetry show --outdated
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="c1"># 檢視相依性樹&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">poetry show --tree&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="相依性樹範例輸出">相依性樹範例輸出&lt;/h5>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">requests 2.31.0 Python HTTP for Humans.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">├── certifi &amp;gt;=2017.4.17
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">├── charset-normalizer &amp;gt;=2,&amp;lt;4
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">├── idna &amp;gt;=2.5,&amp;lt;4
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">└── urllib3 &amp;gt;=1.21.1,&amp;lt;3&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="工作流三虛擬環境管理">工作流三：虛擬環境管理&lt;/h3>
&lt;h4 id="自動環境管理">自動環境管理&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 安裝所有相依性（自動建立虛擬環境）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 僅安裝生產相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">poetry install --only main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="c1"># 安裝包含特定群組&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">poetry install --with dev,docs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="c1"># 排除特定群組&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">poetry install --without docs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="c1"># 安裝 extras&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">poetry install --extras yaml
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">poetry install --all-extras&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="環境操作">環境操作&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 進入虛擬環境 shell&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry shell
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 在虛擬環境中執行命令（不進入 shell）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">poetry run python script.py
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">poetry run pytest
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">poetry run python -c &lt;span class="s2">&amp;#34;import my_package; print(my_package.__version__)&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="c1"># 顯示環境資訊&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">poetry env info
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="c1"># 顯示環境路徑&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">poetry env info --path
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">&lt;span class="c1"># 列出所有環境&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">poetry env list
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">&lt;span class="c1"># 切換 Python 版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">poetry env use python3.11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl">poetry env use 3.12
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl">&lt;span class="c1"># 刪除環境&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">23&lt;/span>&lt;span class="cl">poetry env remove python3.11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">24&lt;/span>&lt;span class="cl">poetry env remove --all&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="環境資訊範例輸出">環境資訊範例輸出&lt;/h5>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">Virtualenv
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">Python: 3.11.6
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">Implementation: CPython
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">Path: /path/to/project/.venv
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">Executable: /path/to/project/.venv/bin/python
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Valid: True
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">Base
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">Platform: darwin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">OS: posix
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">Python: 3.11.6
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">Path: /opt/homebrew/Cellar/python@3.11/3.11.6/Frameworks/Python.framework/Versions/3.11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">Executable: /opt/homebrew/Cellar/python@3.11/3.11.6/Frameworks/Python.framework/Versions/3.11/bin/python3.11&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="工作流四建構與發布">工作流四：建構與發布&lt;/h3>
&lt;h4 id="建構套件">建構套件&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 建構 sdist 和 wheel&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 僅建構 wheel&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">poetry build --format wheel
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="c1"># 建構結果&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">dist/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">├── my_package-1.0.0-py3-none-any.whl
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">└── my_package-1.0.0.tar.gz&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="發布到-pypi">發布到 PyPI&lt;/h4>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 設定 PyPI token&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry config pypi-token.pypi pypi-XXXXXXXXXXXX
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 發布到 PyPI&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">poetry publish
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="c1"># 建構並發布（一步完成）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">poetry publish --build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="c1"># 發布到 TestPyPI&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">poetry config repositories.testpypi https://test.pypi.org/legacy/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">poetry config pypi-token.testpypi pypi-XXXXXXXXXXXX
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">poetry publish --repository testpypi&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="版本管理">版本管理&lt;/h5>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 查看當前版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">poetry version
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 升級版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">poetry version patch &lt;span class="c1"># 1.0.0 -&amp;gt; 1.0.1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">poetry version minor &lt;span class="c1"># 1.0.0 -&amp;gt; 1.1.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">poetry version major &lt;span class="c1"># 1.0.0 -&amp;gt; 2.0.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="c1"># 設定特定版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">poetry version 2.0.0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="c1"># 預發布版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">poetry version prepatch &lt;span class="c1"># 1.0.0 -&amp;gt; 1.0.1a0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">poetry version preminor &lt;span class="c1"># 1.0.0 -&amp;gt; 1.1.0a0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">poetry version premajor &lt;span class="c1"># 1.0.0 -&amp;gt; 2.0.0a0&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="完整-pyprojecttoml-範例">完整 pyproject.toml 範例&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">build-system&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="nx">requires&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;poetry-core&amp;gt;=2.0&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="nx">build-backend&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;poetry.core.masonry.api&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">project&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="nx">name&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;my-awesome-lib&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;1.0.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="nx">description&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;A feature-rich Python library&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="nx">readme&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;README.md&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="nx">license&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;MIT&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="nx">requires-python&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;gt;=3.10&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="nx">authors&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;Your Name&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">email&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;you@example.com&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">&lt;span class="nx">keywords&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;python&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;library&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;utilities&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="nx">classifiers&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Development Status :: 4 - Beta&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Intended Audience :: Developers&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;License :: OSI Approved :: MIT License&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Operating System :: OS Independent&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Programming Language :: Python :: 3&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Programming Language :: Python :: 3.10&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">23&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Programming Language :: Python :: 3.11&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">24&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Programming Language :: Python :: 3.12&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">25&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Programming Language :: Python :: 3.13&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">26&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;Typing :: Typed&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">27&lt;/span>&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">28&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">29&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">urls&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">30&lt;/span>&lt;span class="cl">&lt;span class="nx">Homepage&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/yourname/my-awesome-lib&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">31&lt;/span>&lt;span class="cl">&lt;span class="nx">Documentation&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://my-awesome-lib.readthedocs.io&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">32&lt;/span>&lt;span class="cl">&lt;span class="nx">Repository&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/yourname/my-awesome-lib.git&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">33&lt;/span>&lt;span class="cl">&lt;span class="nx">Changelog&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/yourname/my-awesome-lib/blob/main/CHANGELOG.md&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">34&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">35&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">scripts&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">36&lt;/span>&lt;span class="cl">&lt;span class="nx">my-cli&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;my_awesome_lib.cli:main&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">37&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">38&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">optional-dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">39&lt;/span>&lt;span class="cl">&lt;span class="nx">yaml&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;pyyaml&amp;gt;=6.0&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">40&lt;/span>&lt;span class="cl">&lt;span class="nx">all&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;my-awesome-lib[yaml]&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">41&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">42&lt;/span>&lt;span class="cl">&lt;span class="c"># ===== Poetry 特定設定 =====&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">43&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">44&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">45&lt;/span>&lt;span class="cl">&lt;span class="nx">packages&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[{&lt;/span> &lt;span class="nx">include&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;my_awesome_lib&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;src&amp;#34;&lt;/span> &lt;span class="p">}]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">46&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">47&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">48&lt;/span>&lt;span class="cl">&lt;span class="nx">python&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^3.10&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">49&lt;/span>&lt;span class="cl">&lt;span class="nx">requests&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^2.31&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">50&lt;/span>&lt;span class="cl">&lt;span class="nx">click&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^8.1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">51&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">52&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dev&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">53&lt;/span>&lt;span class="cl">&lt;span class="nx">pytest&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^8.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">54&lt;/span>&lt;span class="cl">&lt;span class="nx">pytest-cov&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^4.1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">55&lt;/span>&lt;span class="cl">&lt;span class="nx">pytest-asyncio&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^0.23&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">56&lt;/span>&lt;span class="cl">&lt;span class="nx">mypy&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^1.10&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">57&lt;/span>&lt;span class="cl">&lt;span class="nx">ruff&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^0.4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">58&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">59&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">docs&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">60&lt;/span>&lt;span class="cl">&lt;span class="nx">optional&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">61&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">62&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">docs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">63&lt;/span>&lt;span class="cl">&lt;span class="nx">mkdocs&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^1.5&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">64&lt;/span>&lt;span class="cl">&lt;span class="nx">mkdocs-material&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^9.5&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">65&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">66&lt;/span>&lt;span class="cl">&lt;span class="c"># ===== 工具設定 =====&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">67&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">68&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ruff&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">69&lt;/span>&lt;span class="cl">&lt;span class="nx">src&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;src&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">70&lt;/span>&lt;span class="cl">&lt;span class="nx">line-length&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">88&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">71&lt;/span>&lt;span class="cl">&lt;span class="nx">target-version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;py310&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">72&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">73&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ruff&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">lint&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">74&lt;/span>&lt;span class="cl">&lt;span class="nx">select&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;E&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;W&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;F&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;I&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;B&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;C4&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;UP&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">75&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">76&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">mypy&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">77&lt;/span>&lt;span class="cl">&lt;span class="nx">python_version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;3.10&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">78&lt;/span>&lt;span class="cl">&lt;span class="nx">strict&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">79&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">80&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">pytest&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ini_options&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">81&lt;/span>&lt;span class="cl">&lt;span class="nx">testpaths&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;tests&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">82&lt;/span>&lt;span class="cl">&lt;span class="nx">addopts&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;-v --tb=short&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="與其他工具的比較">與其他工具的比較&lt;/h2>
&lt;h3 id="poetry-vs-pip">Poetry vs pip&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>操作&lt;/th>
 &lt;th>pip&lt;/th>
 &lt;th>Poetry&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>安裝相依性&lt;/td>
 &lt;td>&lt;code>pip install -r requirements.txt&lt;/code>&lt;/td>
 &lt;td>&lt;code>poetry install&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>新增相依性&lt;/td>
 &lt;td>手動編輯 requirements.txt&lt;/td>
 &lt;td>&lt;code>poetry add package&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>鎖定版本&lt;/td>
 &lt;td>&lt;code>pip freeze &amp;gt; requirements.txt&lt;/code>&lt;/td>
 &lt;td>自動更新 poetry.lock&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>建立環境&lt;/td>
 &lt;td>&lt;code>python -m venv .venv&lt;/code>&lt;/td>
 &lt;td>自動建立&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>執行命令&lt;/td>
 &lt;td>&lt;code>source .venv/bin/activate &amp;amp;&amp;amp; python&lt;/code>&lt;/td>
 &lt;td>&lt;code>poetry run python&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>建構套件&lt;/td>
 &lt;td>&lt;code>python -m build&lt;/code>&lt;/td>
 &lt;td>&lt;code>poetry build&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>發布套件&lt;/td>
 &lt;td>&lt;code>twine upload dist/*&lt;/code>&lt;/td>
 &lt;td>&lt;code>poetry publish&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="poetry-vs-setuptools">Poetry vs setuptools&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>面向&lt;/th>
 &lt;th>setuptools&lt;/th>
 &lt;th>Poetry&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>設定格式&lt;/td>
 &lt;td>pyproject.toml + 可能需要 setup.py&lt;/td>
 &lt;td>僅 pyproject.toml&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>相依性管理&lt;/td>
 &lt;td>需要額外工具&lt;/td>
 &lt;td>內建完整支援&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>環境管理&lt;/td>
 &lt;td>無&lt;/td>
 &lt;td>內建&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>學習曲線&lt;/td>
 &lt;td>較陡（歷史包袱）&lt;/td>
 &lt;td>較平緩&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>C 擴展支援&lt;/td>
 &lt;td>完整&lt;/td>
 &lt;td>不支援&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>生態系統&lt;/td>
 &lt;td>最廣泛&lt;/td>
 &lt;td>持續成長&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="poetry-vs-hatch">Poetry vs Hatch&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>面向&lt;/th>
 &lt;th>Hatch&lt;/th>
 &lt;th>Poetry&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>設計理念&lt;/td>
 &lt;td>PEP 標準優先&lt;/td>
 &lt;td>使用者體驗優先&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>相依性鎖定&lt;/td>
 &lt;td>無內建&lt;/td>
 &lt;td>核心功能&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>環境管理&lt;/td>
 &lt;td>多環境（類似 tox）&lt;/td>
 &lt;td>單一虛擬環境&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>腳本系統&lt;/td>
 &lt;td>完整&lt;/td>
 &lt;td>基本&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>建構後端&lt;/td>
 &lt;td>hatchling&lt;/td>
 &lt;td>poetry-core&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>適用場景&lt;/td>
 &lt;td>開源函式庫&lt;/td>
 &lt;td>應用程式、內部工具&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="實用技巧">實用技巧&lt;/h2>
&lt;h3 id="技巧一善用-lock-檔案">技巧一：善用 Lock 檔案&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># poetry.lock 的重要性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="c1"># - 記錄所有相依性的精確版本（包含間接相依性）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="c1"># - 確保團隊成員、CI/CD 使用相同版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># - 應該提交到版本控制&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="c1"># 根據 lock 檔案安裝（不更新）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">poetry install --no-update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="c1"># 驗證 lock 檔案與 pyproject.toml 一致&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">poetry check --lock
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="c1"># 匯出為 requirements.txt（部署用）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">poetry &lt;span class="nb">export&lt;/span> -f requirements.txt -o requirements.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">poetry &lt;span class="nb">export&lt;/span> -f requirements.txt --with dev -o requirements-dev.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">poetry &lt;span class="nb">export&lt;/span> --without-hashes -o requirements.txt&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="技巧二善用相依性群組">技巧二：善用相依性群組&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c"># 開發相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dev&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="nx">pytest&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^8.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="nx">ruff&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^0.4&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="c"># 可選群組（預設不安裝）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">docs&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="nx">optional&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">docs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="nx">mkdocs&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^1.5&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="c"># CI 專用群組&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ci&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">&lt;span class="nx">optional&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">group&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ci&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">&lt;span class="nx">pytest-cov&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^4.1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">&lt;span class="nx">codecov&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^2.1&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>




&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 安裝特定群組&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">poetry install --with docs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">poetry install --with ci
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="c1"># CI 環境中的安裝&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">poetry install --only main,ci&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="技巧三善用-extras">技巧三：善用 Extras&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">optional-dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c"># 功能性 extras&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="nx">yaml&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;pyyaml&amp;gt;=6.0&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="nx">async&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;httpx&amp;gt;=0.24&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;aiofiles&amp;gt;=23.0&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="c"># 完整安裝&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="nx">all&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;my-package[yaml,async]&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>




&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 使用者安裝方式&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">pip install my-package &lt;span class="c1"># 基本功能&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">pip install &lt;span class="s2">&amp;#34;my-package[yaml]&amp;#34;&lt;/span> &lt;span class="c1"># 包含 YAML 支援&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">pip install &lt;span class="s2">&amp;#34;my-package[all]&amp;#34;&lt;/span> &lt;span class="c1"># 所有功能&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="技巧四本地相依性和-git-相依性">技巧四：本地相依性和 Git 相依性&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c"># 本地路徑相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="nx">my-local-lib&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">path&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;../my-local-lib&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">develop&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="c"># Git 相依性&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="nx">my-git-lib&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">git&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/user/repo.git&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">&lt;span class="nx">my-git-lib&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">git&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/user/repo.git&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">branch&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;develop&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">&lt;span class="nx">my-git-lib&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">git&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/user/repo.git&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">tag&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;v1.0.0&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">&lt;span class="nx">my-git-lib&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">git&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/user/repo.git&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">rev&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;abc123&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="技巧五平台特定相依性">技巧五：平台特定相依性&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">dependencies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="c"># 僅 Windows&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="nx">pywin32&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^306&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">markers&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;sys_platform == &amp;#39;win32&amp;#39;&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="c"># 僅 Linux&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="nx">uvloop&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^0.19&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">markers&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;sys_platform == &amp;#39;linux&amp;#39;&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">&lt;span class="c"># Python 版本限制&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">&lt;span class="nx">typing-extensions&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;^4.0&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">python&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;3.11&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="技巧六poetry-腳本">技巧六：Poetry 腳本&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tool&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">poetry&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">scripts&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="nx">my-cli&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;my_package.cli:main&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="nx">my-tool&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;my_package.tools:run&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>




&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># src/my_package/cli.py&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">click&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="nd">@click.command&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="nd">@click.option&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;--name&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">default&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;World&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Name to greet&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&amp;gt;&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Greet someone.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> &lt;span class="n">click&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">echo&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Hello, &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">!&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> &lt;span class="n">main&lt;/span>&lt;span class="p">()&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>




&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 安裝後即可使用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">my-cli --name Python
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="c1"># 輸出：Hello, Python!&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="常見問題與解決">常見問題與解決&lt;/h2>
&lt;h3 id="問題一相依性解析衝突">問題一：相依性解析衝突&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 錯誤訊息&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">SolverProblemError: ...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 解決方法&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="c1"># 1. 檢視衝突詳情&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">poetry show --tree
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="c1"># 2. 放寬版本限制&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">poetry add &lt;span class="s2">&amp;#34;package&amp;gt;=1.0,&amp;lt;3.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="c1"># 3. 強制更新 lock 檔案&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">poetry lock --no-update&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="問題二虛擬環境問題">問題二：虛擬環境問題&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 重建虛擬環境&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">poetry env remove --all
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">poetry install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="c1"># 指定 Python 版本&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">poetry env use /usr/bin/python3.11&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="問題三cicd-快取">問題三：CI/CD 快取&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c"># GitHub Actions 範例&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Install Poetry&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">snok/install-poetry@v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">virtualenvs-create&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">virtualenvs-in-project&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Load cached venv&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/cache@v4&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">.venv&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">key&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">venv-${{ runner.os }}-${{ hashFiles(&amp;#39;**/poetry.lock&amp;#39;) }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Install dependencies&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">if&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">steps.cache.outputs.cache-hit != &amp;#39;true&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">poetry install --no-interaction&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計權衡">設計權衡&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>面向&lt;/th>
 &lt;th>優點&lt;/th>
 &lt;th>缺點&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>相依性鎖定&lt;/strong>&lt;/td>
 &lt;td>環境可重現、團隊一致&lt;/td>
 &lt;td>lock 檔案衝突、更新需謹慎&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>一體化工具&lt;/strong>&lt;/td>
 &lt;td>學習成本低、工作流統一&lt;/td>
 &lt;td>與其他工具整合需調整&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>虛擬環境整合&lt;/strong>&lt;/td>
 &lt;td>自動管理、不易混淆&lt;/td>
 &lt;td>自訂環境位置需設定&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>建構與發布&lt;/strong>&lt;/td>
 &lt;td>流程簡化&lt;/td>
 &lt;td>不支援 C 擴展&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="練習">練習&lt;/h2>
&lt;h3 id="基礎練習建立-poetry-專案">基礎練習：建立 Poetry 專案&lt;/h3>
&lt;p>&lt;strong>目標&lt;/strong>：使用 Poetry 建立一個簡單的專案&lt;/p></description><content:encoded><![CDATA[<p>本案例展示如何使用 Poetry 管理現代 Python 專案的完整生命週期，從專案建立到套件發布。</p>
<h2 id="先備知識">先備知識</h2>
<ul>
<li><a href="/blog/python-advanced/07-packaging/build-systems/" data-link-title="6.2 建構系統比較" data-link-desc="比較 setuptools、Poetry、Hatch 等建構系統">建構系統比較</a></li>
<li>Python 虛擬環境基礎</li>
<li>套件相依性概念</li>
</ul>
<h2 id="問題背景">問題背景</h2>
<h3 id="現代專案的挑戰">現代專案的挑戰</h3>
<p>傳統的 Python 專案管理面臨以下問題：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">傳統工作流程的痛點：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">├── 相依性管理
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">│   ├── requirements.txt 無法鎖定間接相依性
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">│   ├── pip freeze 產生的版本可能過於嚴格
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">│   └── 開發與生產環境相依性混在一起
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">├── 虛擬環境
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">│   ├── 需要手動建立和管理
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">│   ├── 不同專案的環境容易混淆
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">│   └── 缺乏與專案的關聯性
</span></span><span class="line"><span class="ln">10</span><span class="cl">├── 建構與發布
</span></span><span class="line"><span class="ln">11</span><span class="cl">│   ├── setup.py 設定複雜
</span></span><span class="line"><span class="ln">12</span><span class="cl">│   ├── 發布流程需要多個工具
</span></span><span class="line"><span class="ln">13</span><span class="cl">│   └── 版本管理不一致
</span></span><span class="line"><span class="ln">14</span><span class="cl">└── 團隊協作
</span></span><span class="line"><span class="ln">15</span><span class="cl">    ├── 環境難以重現
</span></span><span class="line"><span class="ln">16</span><span class="cl">    ├── 「在我電腦上可以跑」問題
</span></span><span class="line"><span class="ln">17</span><span class="cl">    └── 新成員上手困難</span></span></code></pre></div><h3 id="為什麼選擇-poetry">為什麼選擇 Poetry？</h3>
<table>
  <thead>
      <tr>
          <th>特性</th>
          <th>pip + venv</th>
          <th>Poetry</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>相依性鎖定</td>
          <td>手動（pip freeze）</td>
          <td>自動（poetry.lock）</td>
      </tr>
      <tr>
          <td>間接相依性追蹤</td>
          <td>無</td>
          <td>完整追蹤</td>
      </tr>
      <tr>
          <td>虛擬環境管理</td>
          <td>手動</td>
          <td>自動整合</td>
      </tr>
      <tr>
          <td>建構系統</td>
          <td>需要額外工具</td>
          <td>內建</td>
      </tr>
      <tr>
          <td>發布流程</td>
          <td>需要 twine</td>
          <td>內建</td>
      </tr>
      <tr>
          <td>相依性群組</td>
          <td>無原生支援</td>
          <td>完整支援</td>
      </tr>
  </tbody>
</table>
<h2 id="解決方案">解決方案</h2>
<h3 id="安裝-poetry">安裝 Poetry</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 官方推薦的安裝方式（獨立安裝）</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">curl -sSL https://install.python-poetry.org <span class="p">|</span> python3 -
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 或使用 pipx（推薦用於 CLI 工具）</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">pipx install poetry
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"># 確認安裝</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">poetry --version</span></span></code></pre></div><h4 id="設定-poetry">設定 Poetry</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 在專案目錄中建立虛擬環境（推薦）</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">poetry config virtualenvs.in-project <span class="nb">true</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 查看所有設定</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">poetry config --list</span></span></code></pre></div><h3 id="工作流一建立新專案">工作流一：建立新專案</h3>
<h4 id="使用-poetry-new完整專案結構">使用 poetry new（完整專案結構）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 建立新專案</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry new my-awesome-lib
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 產生的目錄結構</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">my-awesome-lib/
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">├── pyproject.toml
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">├── README.md
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">├── my_awesome_lib/
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">│   └── __init__.py
</span></span><span class="line"><span class="ln">10</span><span class="cl">└── tests/
</span></span><span class="line"><span class="ln">11</span><span class="cl">    └── __init__.py</span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 使用 src layout（推薦用於函式庫）</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry new --src my-awesome-lib
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 產生的目錄結構</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">my-awesome-lib/
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">├── pyproject.toml
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">├── README.md
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">├── src/
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">│   └── my_awesome_lib/
</span></span><span class="line"><span class="ln">10</span><span class="cl">│       └── __init__.py
</span></span><span class="line"><span class="ln">11</span><span class="cl">└── tests/
</span></span><span class="line"><span class="ln">12</span><span class="cl">    └── __init__.py</span></span></code></pre></div><h4 id="使用-poetry-init現有專案">使用 poetry init（現有專案）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 在現有目錄初始化</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nb">cd</span> existing-project
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">poetry init
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"># 互動式問答</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"># - Package name</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"># - Version</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"># - Description</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># - Author</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"># - License</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"># - Python version</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># - Dependencies</span></span></span></code></pre></div><h5 id="互動式初始化範例">互動式初始化範例</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">This command will guide you through creating your pyproject.toml config.
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">Package name [existing-project]:  my-package
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">Version [0.1.0]:  1.0.0
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">Description []:  A useful Python package
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Author [Your Name &lt;you@example.com&gt;, n to skip]:
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">License []:  MIT
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">Compatible Python versions [^3.10]:  ^3.10
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">Would you like to define your main dependencies interactively? (yes/no) [yes]
</span></span><span class="line"><span class="ln">11</span><span class="cl">Search for package to add (or leave blank to continue): requests
</span></span><span class="line"><span class="ln">12</span><span class="cl">...</span></span></code></pre></div><h3 id="工作流二管理相依性">工作流二：管理相依性</h3>
<h4 id="新增相依性">新增相依性</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 新增生產相依性</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry add requests
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">poetry add <span class="s2">&#34;httpx&gt;=0.24&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"># 新增開發相依性</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">poetry add pytest --group dev
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">poetry add ruff mypy --group dev
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># 新增文件相依性</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">poetry add mkdocs mkdocs-material --group docs
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># 新增可選相依性（extras）</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">poetry add pyyaml --optional</span></span></code></pre></div><h5 id="pyprojecttoml-的變化">pyproject.toml 的變化</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nx">python</span> <span class="p">=</span> <span class="s2">&#34;^3.10&#34;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nx">requests</span> <span class="p">=</span> <span class="s2">&#34;^2.31.0&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nx">httpx</span> <span class="p">=</span> <span class="s2">&#34;&gt;=0.24&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">dev</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="nx">pytest</span> <span class="p">=</span> <span class="s2">&#34;^8.0.0&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="nx">ruff</span> <span class="p">=</span> <span class="s2">&#34;^0.4.0&#34;</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nx">mypy</span> <span class="p">=</span> <span class="s2">&#34;^1.10.0&#34;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">docs</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="nx">mkdocs</span> <span class="p">=</span> <span class="s2">&#34;^1.5.0&#34;</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="nx">mkdocs-material</span> <span class="p">=</span> <span class="s2">&#34;^9.5.0&#34;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">extras</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="nx">yaml</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;pyyaml&#34;</span><span class="p">]</span></span></span></code></pre></div><h4 id="移除相依性">移除相依性</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 移除生產相依性</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">poetry remove requests
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 移除開發相依性</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">poetry remove pytest --group dev</span></span></code></pre></div><h4 id="更新相依性">更新相依性</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 更新所有相依性</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry update
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 更新特定套件</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">poetry update requests
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"># 檢視可更新的套件</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">poetry show --outdated
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"># 檢視相依性樹</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">poetry show --tree</span></span></code></pre></div><h5 id="相依性樹範例輸出">相依性樹範例輸出</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">requests 2.31.0 Python HTTP for Humans.
</span></span><span class="line"><span class="ln">2</span><span class="cl">├── certifi &gt;=2017.4.17
</span></span><span class="line"><span class="ln">3</span><span class="cl">├── charset-normalizer &gt;=2,&lt;4
</span></span><span class="line"><span class="ln">4</span><span class="cl">├── idna &gt;=2.5,&lt;4
</span></span><span class="line"><span class="ln">5</span><span class="cl">└── urllib3 &gt;=1.21.1,&lt;3</span></span></code></pre></div><h3 id="工作流三虛擬環境管理">工作流三：虛擬環境管理</h3>
<h4 id="自動環境管理">自動環境管理</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 安裝所有相依性（自動建立虛擬環境）</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry install
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 僅安裝生產相依性</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">poetry install --only main
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"># 安裝包含特定群組</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">poetry install --with dev,docs
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"># 排除特定群組</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">poetry install --without docs
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1"># 安裝 extras</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">poetry install --extras yaml
</span></span><span class="line"><span class="ln">15</span><span class="cl">poetry install --all-extras</span></span></code></pre></div><h4 id="環境操作">環境操作</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 進入虛擬環境 shell</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry shell
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 在虛擬環境中執行命令（不進入 shell）</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">poetry run python script.py
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">poetry run pytest
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">poetry run python -c <span class="s2">&#34;import my_package; print(my_package.__version__)&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># 顯示環境資訊</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">poetry env info
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># 顯示環境路徑</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">poetry env info --path
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="c1"># 列出所有環境</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">poetry env list
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"># 切換 Python 版本</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">poetry env use python3.11
</span></span><span class="line"><span class="ln">20</span><span class="cl">poetry env use 3.12
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="c1"># 刪除環境</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">poetry env remove python3.11
</span></span><span class="line"><span class="ln">24</span><span class="cl">poetry env remove --all</span></span></code></pre></div><h5 id="環境資訊範例輸出">環境資訊範例輸出</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Virtualenv
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">Python:         3.11.6
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">Implementation: CPython
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">Path:           /path/to/project/.venv
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">Executable:     /path/to/project/.venv/bin/python
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Valid:          True
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">Base
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Platform:   darwin
</span></span><span class="line"><span class="ln">10</span><span class="cl">OS:         posix
</span></span><span class="line"><span class="ln">11</span><span class="cl">Python:     3.11.6
</span></span><span class="line"><span class="ln">12</span><span class="cl">Path:       /opt/homebrew/Cellar/python@3.11/3.11.6/Frameworks/Python.framework/Versions/3.11
</span></span><span class="line"><span class="ln">13</span><span class="cl">Executable: /opt/homebrew/Cellar/python@3.11/3.11.6/Frameworks/Python.framework/Versions/3.11/bin/python3.11</span></span></code></pre></div><h3 id="工作流四建構與發布">工作流四：建構與發布</h3>
<h4 id="建構套件">建構套件</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 建構 sdist 和 wheel</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry build
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 僅建構 wheel</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">poetry build --format wheel
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"># 建構結果</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">dist/
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">├── my_package-1.0.0-py3-none-any.whl
</span></span><span class="line"><span class="ln">10</span><span class="cl">└── my_package-1.0.0.tar.gz</span></span></code></pre></div><h4 id="發布到-pypi">發布到 PyPI</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 設定 PyPI token</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry config pypi-token.pypi pypi-XXXXXXXXXXXX
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 發布到 PyPI</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">poetry publish
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"># 建構並發布（一步完成）</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">poetry publish --build
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"># 發布到 TestPyPI</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">poetry config repositories.testpypi https://test.pypi.org/legacy/
</span></span><span class="line"><span class="ln">12</span><span class="cl">poetry config pypi-token.testpypi pypi-XXXXXXXXXXXX
</span></span><span class="line"><span class="ln">13</span><span class="cl">poetry publish --repository testpypi</span></span></code></pre></div><h5 id="版本管理">版本管理</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 查看當前版本</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">poetry version
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 升級版本</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">poetry version patch   <span class="c1"># 1.0.0 -&gt; 1.0.1</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">poetry version minor   <span class="c1"># 1.0.0 -&gt; 1.1.0</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">poetry version major   <span class="c1"># 1.0.0 -&gt; 2.0.0</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># 設定特定版本</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">poetry version 2.0.0
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># 預發布版本</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">poetry version prepatch  <span class="c1"># 1.0.0 -&gt; 1.0.1a0</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">poetry version preminor  <span class="c1"># 1.0.0 -&gt; 1.1.0a0</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">poetry version premajor  <span class="c1"># 1.0.0 -&gt; 2.0.0a0</span></span></span></code></pre></div><h3 id="完整-pyprojecttoml-範例">完整 pyproject.toml 範例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="p">[</span><span class="nx">build-system</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nx">requires</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;poetry-core&gt;=2.0&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nx">build-backend</span> <span class="p">=</span> <span class="s2">&#34;poetry.core.masonry.api&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="p">[</span><span class="nx">project</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nx">name</span> <span class="p">=</span> <span class="s2">&#34;my-awesome-lib&#34;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="nx">version</span> <span class="p">=</span> <span class="s2">&#34;1.0.0&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="nx">description</span> <span class="p">=</span> <span class="s2">&#34;A feature-rich Python library&#34;</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nx">readme</span> <span class="p">=</span> <span class="s2">&#34;README.md&#34;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="nx">license</span> <span class="p">=</span> <span class="s2">&#34;MIT&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="nx">requires-python</span> <span class="p">=</span> <span class="s2">&#34;&gt;=3.10&#34;</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="nx">authors</span> <span class="p">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">    <span class="p">{</span> <span class="nx">name</span> <span class="p">=</span> <span class="s2">&#34;Your Name&#34;</span><span class="p">,</span> <span class="nx">email</span> <span class="p">=</span> <span class="s2">&#34;you@example.com&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="nx">keywords</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;python&#34;</span><span class="p">,</span> <span class="s2">&#34;library&#34;</span><span class="p">,</span> <span class="s2">&#34;utilities&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="nx">classifiers</span> <span class="p">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="s2">&#34;Development Status :: 4 - Beta&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="s2">&#34;Intended Audience :: Developers&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">    <span class="s2">&#34;License :: OSI Approved :: MIT License&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="s2">&#34;Operating System :: OS Independent&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">    <span class="s2">&#34;Programming Language :: Python :: 3&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">    <span class="s2">&#34;Programming Language :: Python :: 3.10&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="s2">&#34;Programming Language :: Python :: 3.11&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">    <span class="s2">&#34;Programming Language :: Python :: 3.12&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="s2">&#34;Programming Language :: Python :: 3.13&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">    <span class="s2">&#34;Typing :: Typed&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="p">[</span><span class="nx">project</span><span class="p">.</span><span class="nx">urls</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="nx">Homepage</span> <span class="p">=</span> <span class="s2">&#34;https://github.com/yourname/my-awesome-lib&#34;</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="nx">Documentation</span> <span class="p">=</span> <span class="s2">&#34;https://my-awesome-lib.readthedocs.io&#34;</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="nx">Repository</span> <span class="p">=</span> <span class="s2">&#34;https://github.com/yourname/my-awesome-lib.git&#34;</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="nx">Changelog</span> <span class="p">=</span> <span class="s2">&#34;https://github.com/yourname/my-awesome-lib/blob/main/CHANGELOG.md&#34;</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl">
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="p">[</span><span class="nx">project</span><span class="p">.</span><span class="nx">scripts</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="nx">my-cli</span> <span class="p">=</span> <span class="s2">&#34;my_awesome_lib.cli:main&#34;</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl">
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="p">[</span><span class="nx">project</span><span class="p">.</span><span class="nx">optional-dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="nx">yaml</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;pyyaml&gt;=6.0&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="nx">all</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;my-awesome-lib[yaml]&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl">
</span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="c"># ===== Poetry 特定設定 =====</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl">
</span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">45</span><span class="cl"><span class="nx">packages</span> <span class="p">=</span> <span class="p">[{</span> <span class="nx">include</span> <span class="p">=</span> <span class="s2">&#34;my_awesome_lib&#34;</span><span class="p">,</span> <span class="nx">from</span> <span class="p">=</span> <span class="s2">&#34;src&#34;</span> <span class="p">}]</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl">
</span></span><span class="line"><span class="ln">47</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">48</span><span class="cl"><span class="nx">python</span> <span class="p">=</span> <span class="s2">&#34;^3.10&#34;</span>
</span></span><span class="line"><span class="ln">49</span><span class="cl"><span class="nx">requests</span> <span class="p">=</span> <span class="s2">&#34;^2.31&#34;</span>
</span></span><span class="line"><span class="ln">50</span><span class="cl"><span class="nx">click</span> <span class="p">=</span> <span class="s2">&#34;^8.1&#34;</span>
</span></span><span class="line"><span class="ln">51</span><span class="cl">
</span></span><span class="line"><span class="ln">52</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">dev</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">53</span><span class="cl"><span class="nx">pytest</span> <span class="p">=</span> <span class="s2">&#34;^8.0&#34;</span>
</span></span><span class="line"><span class="ln">54</span><span class="cl"><span class="nx">pytest-cov</span> <span class="p">=</span> <span class="s2">&#34;^4.1&#34;</span>
</span></span><span class="line"><span class="ln">55</span><span class="cl"><span class="nx">pytest-asyncio</span> <span class="p">=</span> <span class="s2">&#34;^0.23&#34;</span>
</span></span><span class="line"><span class="ln">56</span><span class="cl"><span class="nx">mypy</span> <span class="p">=</span> <span class="s2">&#34;^1.10&#34;</span>
</span></span><span class="line"><span class="ln">57</span><span class="cl"><span class="nx">ruff</span> <span class="p">=</span> <span class="s2">&#34;^0.4&#34;</span>
</span></span><span class="line"><span class="ln">58</span><span class="cl">
</span></span><span class="line"><span class="ln">59</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">docs</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">60</span><span class="cl"><span class="nx">optional</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln">61</span><span class="cl">
</span></span><span class="line"><span class="ln">62</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">docs</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">63</span><span class="cl"><span class="nx">mkdocs</span> <span class="p">=</span> <span class="s2">&#34;^1.5&#34;</span>
</span></span><span class="line"><span class="ln">64</span><span class="cl"><span class="nx">mkdocs-material</span> <span class="p">=</span> <span class="s2">&#34;^9.5&#34;</span>
</span></span><span class="line"><span class="ln">65</span><span class="cl">
</span></span><span class="line"><span class="ln">66</span><span class="cl"><span class="c"># ===== 工具設定 =====</span>
</span></span><span class="line"><span class="ln">67</span><span class="cl">
</span></span><span class="line"><span class="ln">68</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">ruff</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">69</span><span class="cl"><span class="nx">src</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;src&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">70</span><span class="cl"><span class="nx">line-length</span> <span class="p">=</span> <span class="mi">88</span>
</span></span><span class="line"><span class="ln">71</span><span class="cl"><span class="nx">target-version</span> <span class="p">=</span> <span class="s2">&#34;py310&#34;</span>
</span></span><span class="line"><span class="ln">72</span><span class="cl">
</span></span><span class="line"><span class="ln">73</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">ruff</span><span class="p">.</span><span class="nx">lint</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">74</span><span class="cl"><span class="nx">select</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;E&#34;</span><span class="p">,</span> <span class="s2">&#34;W&#34;</span><span class="p">,</span> <span class="s2">&#34;F&#34;</span><span class="p">,</span> <span class="s2">&#34;I&#34;</span><span class="p">,</span> <span class="s2">&#34;B&#34;</span><span class="p">,</span> <span class="s2">&#34;C4&#34;</span><span class="p">,</span> <span class="s2">&#34;UP&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">75</span><span class="cl">
</span></span><span class="line"><span class="ln">76</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">mypy</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">77</span><span class="cl"><span class="nx">python_version</span> <span class="p">=</span> <span class="s2">&#34;3.10&#34;</span>
</span></span><span class="line"><span class="ln">78</span><span class="cl"><span class="nx">strict</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln">79</span><span class="cl">
</span></span><span class="line"><span class="ln">80</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">pytest</span><span class="p">.</span><span class="nx">ini_options</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">81</span><span class="cl"><span class="nx">testpaths</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;tests&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">82</span><span class="cl"><span class="nx">addopts</span> <span class="p">=</span> <span class="s2">&#34;-v --tb=short&#34;</span></span></span></code></pre></div><h2 id="與其他工具的比較">與其他工具的比較</h2>
<h3 id="poetry-vs-pip">Poetry vs pip</h3>
<table>
  <thead>
      <tr>
          <th>操作</th>
          <th>pip</th>
          <th>Poetry</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>安裝相依性</td>
          <td><code>pip install -r requirements.txt</code></td>
          <td><code>poetry install</code></td>
      </tr>
      <tr>
          <td>新增相依性</td>
          <td>手動編輯 requirements.txt</td>
          <td><code>poetry add package</code></td>
      </tr>
      <tr>
          <td>鎖定版本</td>
          <td><code>pip freeze &gt; requirements.txt</code></td>
          <td>自動更新 poetry.lock</td>
      </tr>
      <tr>
          <td>建立環境</td>
          <td><code>python -m venv .venv</code></td>
          <td>自動建立</td>
      </tr>
      <tr>
          <td>執行命令</td>
          <td><code>source .venv/bin/activate &amp;&amp; python</code></td>
          <td><code>poetry run python</code></td>
      </tr>
      <tr>
          <td>建構套件</td>
          <td><code>python -m build</code></td>
          <td><code>poetry build</code></td>
      </tr>
      <tr>
          <td>發布套件</td>
          <td><code>twine upload dist/*</code></td>
          <td><code>poetry publish</code></td>
      </tr>
  </tbody>
</table>
<h3 id="poetry-vs-setuptools">Poetry vs setuptools</h3>
<table>
  <thead>
      <tr>
          <th>面向</th>
          <th>setuptools</th>
          <th>Poetry</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>設定格式</td>
          <td>pyproject.toml + 可能需要 setup.py</td>
          <td>僅 pyproject.toml</td>
      </tr>
      <tr>
          <td>相依性管理</td>
          <td>需要額外工具</td>
          <td>內建完整支援</td>
      </tr>
      <tr>
          <td>環境管理</td>
          <td>無</td>
          <td>內建</td>
      </tr>
      <tr>
          <td>學習曲線</td>
          <td>較陡（歷史包袱）</td>
          <td>較平緩</td>
      </tr>
      <tr>
          <td>C 擴展支援</td>
          <td>完整</td>
          <td>不支援</td>
      </tr>
      <tr>
          <td>生態系統</td>
          <td>最廣泛</td>
          <td>持續成長</td>
      </tr>
  </tbody>
</table>
<h3 id="poetry-vs-hatch">Poetry vs Hatch</h3>
<table>
  <thead>
      <tr>
          <th>面向</th>
          <th>Hatch</th>
          <th>Poetry</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>設計理念</td>
          <td>PEP 標準優先</td>
          <td>使用者體驗優先</td>
      </tr>
      <tr>
          <td>相依性鎖定</td>
          <td>無內建</td>
          <td>核心功能</td>
      </tr>
      <tr>
          <td>環境管理</td>
          <td>多環境（類似 tox）</td>
          <td>單一虛擬環境</td>
      </tr>
      <tr>
          <td>腳本系統</td>
          <td>完整</td>
          <td>基本</td>
      </tr>
      <tr>
          <td>建構後端</td>
          <td>hatchling</td>
          <td>poetry-core</td>
      </tr>
      <tr>
          <td>適用場景</td>
          <td>開源函式庫</td>
          <td>應用程式、內部工具</td>
      </tr>
  </tbody>
</table>
<h2 id="實用技巧">實用技巧</h2>
<h3 id="技巧一善用-lock-檔案">技巧一：善用 Lock 檔案</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># poetry.lock 的重要性</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"># - 記錄所有相依性的精確版本（包含間接相依性）</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"># - 確保團隊成員、CI/CD 使用相同版本</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># - 應該提交到版本控制</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"># 根據 lock 檔案安裝（不更新）</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">poetry install --no-update
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># 驗證 lock 檔案與 pyproject.toml 一致</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">poetry check --lock
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># 匯出為 requirements.txt（部署用）</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">poetry <span class="nb">export</span> -f requirements.txt -o requirements.txt
</span></span><span class="line"><span class="ln">14</span><span class="cl">poetry <span class="nb">export</span> -f requirements.txt --with dev -o requirements-dev.txt
</span></span><span class="line"><span class="ln">15</span><span class="cl">poetry <span class="nb">export</span> --without-hashes -o requirements.txt</span></span></code></pre></div><h3 id="技巧二善用相依性群組">技巧二：善用相依性群組</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c"># 開發相依性</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">dev</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nx">pytest</span> <span class="p">=</span> <span class="s2">&#34;^8.0&#34;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nx">ruff</span> <span class="p">=</span> <span class="s2">&#34;^0.4&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c"># 可選群組（預設不安裝）</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">docs</span><span class="p">]</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="nx">optional</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">docs</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="nx">mkdocs</span> <span class="p">=</span> <span class="s2">&#34;^1.5&#34;</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c"># CI 專用群組</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">ci</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="nx">optional</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">group</span><span class="p">.</span><span class="nx">ci</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="nx">pytest-cov</span> <span class="p">=</span> <span class="s2">&#34;^4.1&#34;</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="nx">codecov</span> <span class="p">=</span> <span class="s2">&#34;^2.1&#34;</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 安裝特定群組</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">poetry install --with docs
</span></span><span class="line"><span class="ln">3</span><span class="cl">poetry install --with ci
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"># CI 環境中的安裝</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">poetry install --only main,ci</span></span></code></pre></div><h3 id="技巧三善用-extras">技巧三：善用 Extras</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">[</span><span class="nx">project</span><span class="p">.</span><span class="nx">optional-dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c"># 功能性 extras</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">yaml</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;pyyaml&gt;=6.0&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="nx">async</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;httpx&gt;=0.24&#34;</span><span class="p">,</span> <span class="s2">&#34;aiofiles&gt;=23.0&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c"># 完整安裝</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="nx">all</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;my-package[yaml,async]&#34;</span><span class="p">]</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 使用者安裝方式</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">pip install my-package           <span class="c1"># 基本功能</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">pip install <span class="s2">&#34;my-package[yaml]&#34;</span>   <span class="c1"># 包含 YAML 支援</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">pip install <span class="s2">&#34;my-package[all]&#34;</span>    <span class="c1"># 所有功能</span></span></span></code></pre></div><h3 id="技巧四本地相依性和-git-相依性">技巧四：本地相依性和 Git 相依性</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c"># 本地路徑相依性</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">my-local-lib</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">path</span> <span class="p">=</span> <span class="s2">&#34;../my-local-lib&#34;</span><span class="p">,</span> <span class="nx">develop</span> <span class="p">=</span> <span class="kc">true</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c"># Git 相依性</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="nx">my-git-lib</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">git</span> <span class="p">=</span> <span class="s2">&#34;https://github.com/user/repo.git&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="nx">my-git-lib</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">git</span> <span class="p">=</span> <span class="s2">&#34;https://github.com/user/repo.git&#34;</span><span class="p">,</span> <span class="nx">branch</span> <span class="p">=</span> <span class="s2">&#34;develop&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="nx">my-git-lib</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">git</span> <span class="p">=</span> <span class="s2">&#34;https://github.com/user/repo.git&#34;</span><span class="p">,</span> <span class="nx">tag</span> <span class="p">=</span> <span class="s2">&#34;v1.0.0&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="nx">my-git-lib</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">git</span> <span class="p">=</span> <span class="s2">&#34;https://github.com/user/repo.git&#34;</span><span class="p">,</span> <span class="nx">rev</span> <span class="p">=</span> <span class="s2">&#34;abc123&#34;</span> <span class="p">}</span></span></span></code></pre></div><h3 id="技巧五平台特定相依性">技巧五：平台特定相依性</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">dependencies</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c"># 僅 Windows</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">pywin32</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">version</span> <span class="p">=</span> <span class="s2">&#34;^306&#34;</span><span class="p">,</span> <span class="nx">markers</span> <span class="p">=</span> <span class="s2">&#34;sys_platform == &#39;win32&#39;&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c"># 僅 Linux</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="nx">uvloop</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">version</span> <span class="p">=</span> <span class="s2">&#34;^0.19&#34;</span><span class="p">,</span> <span class="nx">markers</span> <span class="p">=</span> <span class="s2">&#34;sys_platform == &#39;linux&#39;&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">
</span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="c"># Python 版本限制</span>
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="nx">typing-extensions</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">version</span> <span class="p">=</span> <span class="s2">&#34;^4.0&#34;</span><span class="p">,</span> <span class="nx">python</span> <span class="p">=</span> <span class="s2">&#34;&lt;3.11&#34;</span> <span class="p">}</span></span></span></code></pre></div><h3 id="技巧六poetry-腳本">技巧六：Poetry 腳本</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">[</span><span class="nx">tool</span><span class="p">.</span><span class="nx">poetry</span><span class="p">.</span><span class="nx">scripts</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nx">my-cli</span> <span class="p">=</span> <span class="s2">&#34;my_package.cli:main&#34;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="nx">my-tool</span> <span class="p">=</span> <span class="s2">&#34;my_package.tools:run&#34;</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># src/my_package/cli.py</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="kn">import</span> <span class="nn">click</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nd">@click.command</span><span class="p">()</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="nd">@click.option</span><span class="p">(</span><span class="s2">&#34;--name&#34;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&#34;World&#34;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&#34;Name to greet&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="s2">&#34;&#34;&#34;Greet someone.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="n">click</span><span class="o">.</span><span class="n">echo</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Hello, </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&#34;__main__&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="n">main</span><span class="p">()</span></span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 安裝後即可使用</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">my-cli --name Python
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="c1"># 輸出：Hello, Python!</span></span></span></code></pre></div><h2 id="常見問題與解決">常見問題與解決</h2>
<h3 id="問題一相依性解析衝突">問題一：相依性解析衝突</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 錯誤訊息</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">SolverProblemError: ...
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 解決方法</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"># 1. 檢視衝突詳情</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">poetry show --tree
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"># 2. 放寬版本限制</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">poetry add <span class="s2">&#34;package&gt;=1.0,&lt;3.0&#34;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"># 3. 強制更新 lock 檔案</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">poetry lock --no-update</span></span></code></pre></div><h3 id="問題二虛擬環境問題">問題二：虛擬環境問題</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 重建虛擬環境</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">poetry env remove --all
</span></span><span class="line"><span class="ln">3</span><span class="cl">poetry install
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"># 指定 Python 版本</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">poetry env use /usr/bin/python3.11</span></span></code></pre></div><h3 id="問題三cicd-快取">問題三：CI/CD 快取</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c"># GitHub Actions 範例</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="w"></span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Install Poetry</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="w">  </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">snok/install-poetry@v1</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="w">  </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="w">    </span><span class="nt">virtualenvs-create</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="w">    </span><span class="nt">virtualenvs-in-project</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="w"></span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Load cached venv</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="w">  </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/cache@v4</span><span class="w">
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="w">  </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="w">    </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">.venv</span><span class="w">
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="w">    </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">venv-${{ runner.os }}-${{ hashFiles(&#39;**/poetry.lock&#39;) }}</span><span class="w">
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="w"></span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Install dependencies</span><span class="w">
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="w">  </span><span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">steps.cache.outputs.cache-hit != &#39;true&#39;</span><span class="w">
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="w">  </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">poetry install --no-interaction</span></span></span></code></pre></div><h2 id="設計權衡">設計權衡</h2>
<table>
  <thead>
      <tr>
          <th>面向</th>
          <th>優點</th>
          <th>缺點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>相依性鎖定</strong></td>
          <td>環境可重現、團隊一致</td>
          <td>lock 檔案衝突、更新需謹慎</td>
      </tr>
      <tr>
          <td><strong>一體化工具</strong></td>
          <td>學習成本低、工作流統一</td>
          <td>與其他工具整合需調整</td>
      </tr>
      <tr>
          <td><strong>虛擬環境整合</strong></td>
          <td>自動管理、不易混淆</td>
          <td>自訂環境位置需設定</td>
      </tr>
      <tr>
          <td><strong>建構與發布</strong></td>
          <td>流程簡化</td>
          <td>不支援 C 擴展</td>
      </tr>
  </tbody>
</table>
<h2 id="練習">練習</h2>
<h3 id="基礎練習建立-poetry-專案">基礎練習：建立 Poetry 專案</h3>
<p><strong>目標</strong>：使用 Poetry 建立一個簡單的專案</p>
<ol>
<li>使用 <code>poetry new --src my-utils</code> 建立專案</li>
<li>新增 <code>requests</code> 作為生產相依性</li>
<li>新增 <code>pytest</code> 和 <code>ruff</code> 作為開發相依性</li>
<li>執行 <code>poetry install</code> 並驗證環境</li>
</ol>
<h3 id="進階練習設定相依性群組">進階練習：設定相依性群組</h3>
<p><strong>目標</strong>：建立完整的相依性管理結構</p>
<ol>
<li>建立 <code>dev</code>、<code>docs</code>、<code>ci</code> 三個群組</li>
<li>將 <code>docs</code> 和 <code>ci</code> 設為可選群組</li>
<li>練習使用 <code>--with</code> 和 <code>--without</code> 選項</li>
</ol>
<h3 id="挑戰題完整發布流程">挑戰題：完整發布流程</h3>
<p><strong>目標</strong>：將專案發布到 TestPyPI</p>
<ol>
<li>設定 TestPyPI repository</li>
<li>使用 <code>poetry version</code> 管理版本</li>
<li>執行 <code>poetry build</code> 建構套件</li>
<li>執行 <code>poetry publish --repository testpypi</code> 發布</li>
</ol>
<h2 id="延伸閱讀">延伸閱讀</h2>
<ul>
<li><a href="https://python-poetry.org/docs/">Poetry 官方文件</a></li>
<li><a href="https://python-poetry.org/docs/cli/">Poetry CLI 參考</a></li>
<li><a href="https://peps.python.org/pep-0621/">pyproject.toml 規範 (PEP 621)</a></li>
<li><a href="https://packaging.python.org/">Python 打包使用者指南</a></li>
</ul>
<hr>
<p>返回：<a href="/blog/python-advanced/07-packaging/case-studies/" data-link-title="案例研究" data-link-desc="基於 .claude/lib 實際程式碼的打包發布案例">案例研究</a></p>
]]></content:encoded></item></channel></rss>