大概在三年半前
我曾經寫過Python 3.8的環境建設
隨著時間的快速推進
現在Python版本已經來到了3.13-dev
因此今天就花點時間Update一下我們的資訊吧

# 前言

Python是一門很有趣的程式語言
雖然在效能上的消耗遠不如Golang或Rust等語言
但在社群支援度和套件豐富度上
Python的強悍足以和NodeJS的生態系相比擬
擁有趨近於予取予求的現成套件量

經過了將近四年的磨練後
筆者也算是對Python與環境有了更多的認識
本篇文章就手把手的教你如何建立Python的開發環境

# 觀前提示

  • 本篇文章將主要以CLI方式進行 若有使用上的需求可以參考CLI工作訣竅
  • 本文適用於主流的MacOS、Linux、Windows系統
  • 本文將以Python3.12為案例進行說明 若需求不同請自行調整
  • 請務必知道你自己在做什麼 希望你不要把電腦搞壞

# Python環境的安裝

# Python本體

根據使用的作業系統不同
Python的安裝方式也會有所不同
以下將分別簡單介紹

Windows系統中有兩種安裝模式

  1. 直接至官網下載安裝包
  1. 透過Microsoft Store安裝

MacOS系統下內建就有安裝Python
需要更新的時候更新就好
如果有需求要安裝
我們有兩種方式可以進行安裝

  1. 透過Homebrew安裝
brew install python
  1. 透過官網下載安裝包

絕多數的Linux發行版中都會自帶Python
如果沒有安裝的話
依照系統的不同 我們可以在Terminal中輸入

sudo apt-get install python3 # Ubuntu
sudo yum install python3 # CentOS
sudo pacman -S python3 # Arch
sudo dnf install python3 # Fedora

# Python套件管理器

Python的特色之一便是擁有豐富的套件
而這些套件的管理基本上會透過pip這個套件管理器進行

# 安裝pip

在Python3.4之後 pip已經內建在Python裡了
如果你的Python版本是3.4以上
恭喜你 我不太覺得現在會有人用這麼舊的版本
代表你的pip已經安裝只需要更新即可

pip install --upgrade pip # 更新pip
python3 -m pip install --upgrade pip # 如果你是windows的話

# 嘗試安裝套件

我們可以嘗試安裝一些套件來測試pip是否正常運作

pip install requests # 安裝requests套件

接著隨便建立一個app.py
試著測試我們的套件是否可以正常運作

import requests # 引入requests套件
print(requests.get('https://www.google.com').status_code) # 對Google發送請求並印出狀態碼

如果沒有在import階段就報錯
那代表我們的套件是有引用成功的
如此一來代表我們的Python環境已經建立完成了

# Requirements.txt與套件依賴

在Python的開發中
往往不會只需要一個套件就能夠完成開發
相反地 套件一裝總是就會有很多個
而這些套件之間的可能也會彼此依賴
依賴關係也是一個很大的問題
這時候我們就可以使用requirements.txt來進行套件的管理

pip freeze > requirements.txt # 將當前的套件列表寫入requirements.txt
pip install -r requirements.txt # 根據requirements.txt安裝套件

requirements.txt的內容會長得像這樣

requests==2.26.0

這個檔案會幫你記錄你需要什麼樣的套件
以及需要什麼樣的版本以完成任務
這樣一來就可以避免套件的版本衝突問題了
並且在進行板控時
可以直接使用這個檔案來安裝套件
不需要將整個套件包整個上傳也能夠完成安裝

# 大問題

我們的小明今天安裝了一個大套件
然而他發現他裝錯了
於是他從他的專案中刪掉這個套件
問題來了 這個某些依賴受到影響並互相干擾
並且其他專案也無法使用這個套件了
此時應該怎麼做呢

# 虛擬環境

對於環境衝突的問題
如果熟悉NodeJS的使用者應該知道
NodeJS會以專案為單位進行套件的管理
而使用package.json進行套件的記錄
並將套件安裝在專案資料夾的node_modules

然而預設的Python並不會這麼做
使用pip安裝的套件將會全部安裝在Python的套件資料夾中
此時 我們可以利用虛擬環境來解決這個問題

# 挑選虛擬環境

Python的虛擬環境有很多款
包括但不限於

  • venv
  • conda
  • pipenv
  • poetry

筆者我本篇的文章將會以poetry為主
因此將會介紹僅會簡單介紹其他款
並將本期文章的重點將會著重在後者的使用上

# 其他虛擬環境簡介

venv是Python內建的虛擬環境
使用起來非常方便

python3 -m venv venv # 創建虛擬環境
source venv/bin/activate # 啟動虛擬環境
deactivate # 關閉虛擬環境

這樣一來我們就可以在虛擬環境中進行套件的安裝
將虛擬環境以專案為單位進行隔離
如此一來即可避免環境混淆的問題

然而venv的問題在於
它實在是太土砲了
僅僅只有虛擬環境的功能
並沒有一個很好的辦法去控管我們的環境設置和套件相容

conda是一個市場蠻廣泛但我個人並不常使用的虛擬環境
有許多玩AI的開發者會使用這款管理器
對套件的支持度也相當不錯

conda create -n myenv python=3.12 # 創建虛擬環境
conda activate myenv # 啟動虛擬環境
conda deactivate # 關閉虛擬環境

這樣一來我們就可以在虛擬環境中進行套件的安裝
然而為什麼如此強大的套件管理器我個人並不常用呢
原因是因為它太肥了
就如同visual studio一樣
好用歸好用 但平常進行小專案開發
並不會想要殺雞用牛刀
conda的巨量套件和龐大的安裝包成為了它的致命傷

pipenv是一個為了解決Pip問題而誕生的套件管理器

  • 自動生成requirements.txt
  • 自動生成Pipfile
  • 自動生成Pipfile.lock

使用上也很簡單

pipenv install requests # 安裝requests套件
pipenv shell # 進入虛擬環境
exit # 退出虛擬環境

然而 這款雖然跟我們要介紹的Poetry有點類似
但卻有著Lock太慢、Windows支援度差、對PyPI打包支援度很差的種種問題
同時社群維護又不夠好
因此也被眾多Poetry的使用者所詬病

# poetry

這是今天的重中之重
poetry是一個專為Python開發者打造的套件管理器
筆者我本人平時也是使用這牌的環境管理器進行開發作業
這個套件管理器的特色在於

它就是很好用

咳 這樣講可能有點籠統
簡單來說Poetry具有一下優點

  • 擁有非常好的規範和拓展性
  • 對於環境管理的安全性和可移植性也有很高的上限
  • 最重要的是 安裝非常的簡單直白、輕量且容易上手
  • 社群維護度高 官方文檔清楚

並且Poetry可以說整合了Pip和venv的功能
於是乎 我們就來一探這厲害又方便的套件管理器吧

# 安裝

Poetry的安裝在官方文檔中有非常詳細的說明
幾乎不需要額外配置 只需要安裝完成即可使用

pipx install poetry

# 使用curl

curl -sSL https://install.python-poetry.org | python3 -

# 使用powershell

(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -

依照官方安裝的腳本
預設的路徑會是

  • $HOME/.poetry/bin: Unix
  • %appdata%\Python\Scripts: Windows

安裝時是可以設定安裝路徑的
只是如果你直接使用上述的指令安裝的話應該都會在預設位置
此時我們可以修改一下環境變數來讓我們的Poetry更方便使用

export PATH="$HOME/.poetry/bin:$PATH" # Unix
$env:Path = "$env:Path;$HOME\.poetry\bin" # Windows

如此一來我們就可以直接在任何地方直接使用指令召喚Poetry啦

# 初始化專案

首先我們進入專案資料夾內

mkdir myproject # 創建專案資料夾
cd myproject # 進入專案資料夾

隨便開一個新的檔案結構

$ tree
.
├── app.py
└── src/
1 directory, 1 files

此時 重點來了
我們需要對專案進行初始化

poetry init

緊接著會跳出一連串的互動式問題
這些是幫助你提前設定好你的專案的基本資訊
如果你看不懂的話可以無腦的按enter下去沒有關係
這些內容在未來也可以再做修改

問題大概長這樣(點擊展開)
$ poetry init
This command will guide you through creating your pyproject.toml config.

Package name [poetry-demo]:
Version [0.1.0]:
Description []:
Author [miyago9267 <mail>, n to skip]:
License []:
Compatible Python versions [^3.12]:

Would you like to define your main dependencies interactively? (yes/no) [yes]
You can specify a package in the following forms:
  - A single name (requests): this will search for matches on PyPI
  - A name and a constraint (requests@^2.23.0)
  - A git url (git+https://github.com/python-poetry/poetry.git)
  - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)
  - A file path (../my-package/my-package.whl)
  - A directory (../my-package/)
  - A url (https://example.com/packages/my-package-0.1.0.tar.gz)

Package to add or search for (leave blank to skip):

Would you like to define your development dependencies interactively? (yes/no) [yes]
Package to add or search for (leave blank to skip):

Generated file

[tool.poetry]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = ["miyago9267 <mail>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"


Do you confirm generation? (yes/no) [yes]

此時你會看到互動問題的最後面
提示你是否確認生成一個pyproject.toml檔案
確認後再重新檢查一次檔案結構可以看到一個新的檔案出現在專案中

$ tree
.
├── app.py
├── pyproject.toml
└── src/

2 directories, 2 files

理論上此時我們的專案就初始化完畢
可以開始進行套件的安裝和開發流程了
但此時 麻煩先幫我打上一條指令
理由等等會再做解釋

poetry config virtualenvs.in-project true # 強制venv生成於專案內

# 套件安裝

都完成後我們就可以開始安裝我們需要的套件進行開發了
我們可以這樣去從PyPI的套件庫尋找並安裝我們需要的套件

poetry add <package> # 安裝套件
poetry add requests # 嘗試安裝requests套件

並可以使用以下指令來查看我們的套件列表

poetry show # 查看套件列表

此時我們的pyproject.toml會發生變化

[tool.poetry.dependencies]
python = "^3.11"
requests = "^2.31.0"

可以看到在[tool.poetry.dependencies]
多了一個requests的套件
以及記錄著版本下限
代表著之後如果要引用會從這裡調用資料進行安裝

並且除了原本的pyproject.toml檔案外
系統還會多產生一個poetry.lock檔案
這個檔案實際上就相當於pip中的requirements.txt
這個檔案會記錄著我們的套件的當前安裝的版本和內容
絕多數時候裡頭的內容取決於pyproject.toml的內容
不過有時候手動修改pyproject.toml的內容時
例如手動的套件更新 或者新增了額外的安裝鏡像
我們可以透過

poetry lock # 更新poetry.lock

進行依賴文件的更新

# 虛擬環境

基本上在安裝套件的同時
Poetry就會自動幫我們生成一個虛擬環境
若尚未安裝套件的話
則會在進入虛擬環境後自動安裝

在Poetry中
和其他虛擬環境管理軟體一樣
我們也可以使用以下指令來進入虛擬環境

poetry shell # 進入虛擬環境
exit # 退出虛擬環境
poetry run <command> # 在虛擬環境中執行指令

在執行poetry shell
會檢查當前環境是否存在於專案內
若否的話則會噴錯給你看喔

# 虛擬環境的位置

前面提到 Poetry在進入虛擬環境時會產生一份自己的虛擬環境資源
然而 這個環境會被放在一些很神奇的位置
並且會害你在調整版本時由於檔案位置的緣故摸不著頭腦
因此 我個人習慣會使用上面提過的指令
來讓一份虛擬環境強制放入專案內
使得專案與環境的映射更加明確

poetry config virtualenvs.in-project true # 強制venv生成於專案內

如果不小心沒有設定的話也不要緊
我們可以透過以下指令來查看我們的虛擬環境的位置

poetry env info # 查看虛擬環境位置

之後再透過以下的指令來進行設定

poetry env remove <path> # 移除虛擬環境
poetry config virtualenvs.in-project true # 強制venv生成於專案內
poetry env use python # 設定虛擬環境位置

# 輸出requirements.txt

雖然在Poetry中我們已經有了poetry.lock檔案
並且功能幾乎與requirements.txt等價
但並非代表我們不需要requirements.txt
有時候我們需要將我們的專案交給其他人
或者需要包成docker等服務時
我們不可能要求目標環境也安裝Poetry

因此我們可以透過以下指令來將我們的poetry.lock輸出成requirements.txt

poetry export -f requirements.txt -o requirements.txt --without-hashes
注意

預設的輸出檔案中會有hash值影響閱讀
後面的-without-hashes會將requirements.txt中的hash值去除
但有時候Hash會有重要的功用
因此後面的參數要視情況做使用
參考資料 - Github Issue

# 上版後的操作

今天假設我們在遠端開發了一個段落
我們將專案推上了Git的遠端儲存庫
並且在另一台電腦上進行了Clone
理論上 我們並不會把.venv__pycache__等檔案推上去
因此我們在Clone下來後是沒有裝好的虛擬環境的

此時我們當然不用一步一步重新安裝過一次
而是可以用以下指令
直接調用已存在的pyproject.tomlpoetry.lock來進行安裝

poetry install

此時Poetry會自動幫我們安裝我們在pyproject.toml中所記錄的套件
並且會自動重新生成一份虛擬環境的資料
如此一來我們就能在另一台電腦上使用環境啦

# Pyenv的相容性

這裡是一段小小的實用工具補充
在NodeJS中有所謂的NVM可以進行Node的版控切換
而在Python中也有一個類似的工具

叫做Pyenv

Pyenv是一個可以讓你在同一台電腦上安裝多個Python版本的工具
並且可以進行系統、全域、本地版本的切換
如果同一系統中同時有需要新、舊版本的專案需求時
這會是一個很好用的版本控制器
並且能夠一定程度上與Poetry相容
不過礙於主題與篇幅問題
本文並不會展開解說
附錄中會放官方的Github文檔
有興趣可以自行研究

# 結語

今天我們學習了如何在Python中建立一個開發環境
並且學習了如何使用Poetry進行套件的管理

下一期應該會正式開啟一些Python的基礎教學
不過重點並不會著重在程式語言的基本語法和觀念
而是談一談一些在Python開發中值得分享的眉角
那麼下次見啦

# 參考資料

# 附錄

總瀏覽次數:載入中...更新於

請我喝[茶]~( ̄▽ ̄)~*

Miyago9267 微信支付

微信支付

Miyago9267 支付寶

支付寶

Miyago9267 buymeacoffee

buymeacoffee