開發程式的過程中, 可能會遇到 Python 版本不相符的狀況。像是有些程式碼使用了新版本 Python 的語法或是功能, 但是你的環境安裝的是舊版本的 Python, 導致無法正常執行, 舉例來說, 以下的程式在 Python 3.12 之前的版本會出錯: ```python >>> import sys >>> sys.version '3.11.6 (tags/v3.11.6:8b6ee5b, Oct 2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)]' >>> students = [{'name': '王小明'}] >>> f'{students[0]['name']}' Syntax Error: f-string: unmatched '[' (<input>, line 1) ``` 由於在 f-字串內的大括號中使用了英文單引號, 會被視為與字串開頭的引號配對, 導致字串結束, 所以錯誤訊息中指出大括號內的左方括號沒有配對的右方括號。 同樣的程式在 Python 3.12 中就不會有問題: ```python >>> import sys >>> sys.version '3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)]' >>> students = [{'name': '王小明'}] >>> f'{students[0]['name']}' '王小明' ``` 這就是因為在 3.12 中, f-字串會把大括號內的部分單獨解譯, 不會和字串的其他部分混淆。如果為了要執行這個使用了新版本 Python 功能的程式而升級, 又會擔心會不會因為新版本 Python 拿掉了某些舊版 Python 語法或功能. 導致本來跑得好好的程式出問題。 ## Windows 平台 Python 版本管理方法--Python Launcher 在 Windows 平台上, Python 預設會安裝 [Python Launcher](https://docs.python.org/3/using/windows.html#python-launcher-for-windows), 可以管理所有透過 Python 官網下載安裝的 Python 版本, 你可以透過 `py --list` 顯示系統目前安裝的 Python 版本: ```shell! # py --list -V:3.12 * Python 3.12 (64-bit) -V:3.11 Python 3.11 (64-bit) -V:3.9 Python 3.9 (64-bit) ``` 表示我的系統上安裝有三種版本的 Python。 ### 指定使用的 Python 版本 要使用特定版本的 Python 時, 只要如下下達指令即可: ```shell! # py -3.11 Python 3.11.6 (tags/v3.11.6:8b6ee5b, Oct 2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z # py -3.12 Python 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` 如果沒有指定版本, 預設就會執行最新的版本: ```shell! # py Python 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` ### 使用設定檔指定預設版本 如果想變更不指定版本時的預設版本, 可以在 LocalAppData 環境變數所指向的資料夾下建立一個 py.ini 檔, 例如: ```shell # cd $env:localappdata # cat py.ini [defaults] python=3.9 ``` 就可以設定預設版本為 3.9, 如果列出所有版本檢查: ```shell # py --list -V:3.12 Python 3.12 (64-bit) -V:3.11 Python 3.11 (64-bit) -V:3.9 * Python 3.9 (64-bit) # py Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` 你會看到現在 3.9 版有標示 * 符號, 表示預設為 3.9 版, 不指定版本直接執行 py 就會是 3.9 版了。 這個設定檔也可以放在與 py 程式檔相同的資料夾中, 但是優先採用 LocalAppData 中的設定。 ### 依照主版本設定預設版本 你也可以針對 Python2 或是 Python3 設定個別的預設版本, 例如若安裝了以下版本: ```shell # py --list -V:3.12 * Python 3.12 (64-bit) -V:3.11 Python 3.11 (64-bit) -V:3.9 Python 3.9 (64-bit) -V:3.9-32 Python 3.9 (32-bit) -V:2.7 Python 2.7 ``` 若是如下撰寫設定檔, 就只會針對指定主版本為 3 時採用 32 位元的 Python 3.9.x: ```shell # cat py.ini [defaults] python3=3.9-32 ``` 如果執行 py 時沒有指定版本, 由於設定檔中只針對 Python3 設定, 因此不在設定檔的管轄範圍內, 仍會找已安裝的最新版本, 也就是 3.12.1: ```shell # py Python 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> ^Z ``` 但若是指定使用主版本 3, 就會因為設定檔的關係, 採用指定的 32 位元 3.9.x 版: ```shell # py -3 Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:04:37) [MSC v.1929 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` 如果沒有特別指定 32 位元或是 64 位元, 就還是會以 64 位元優先。如果指定使用主版本 2, 就會執行 2.x 版的 Python: ```shell # py -2 Python 2.7.17 (v2.7.17:c2f86d86e6, Oct 19 2019, 21:01:17) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` 你也可以改用環境變數設定預設版本, 只要將設定檔中的設定名稱加上 "PY_" 字頭即可, 環境變數的設定會蓋過設定檔的內容。例如透過環境變數設定主版本 3 預設使用 3.11.x 版: ```shell # $env:PY_PYTHON3 = '3.11' # py -3 Python 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` 現在就以環境變數優先, 當指定主版本 3 的 Python 時, 就會使用 3.11.3 版, 而不是剛剛設定檔中的 3.9.x 版了。 在 Windows 中環境變數並不區分大小寫, 只是慣例上都採用全部大寫, 所以像是以下就可以讓指定主版本 3 時使用 3.12.x 版了: ```shell # $env:py_python3 = '3.12' # py -3 Python 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` ## 使用 shebang 指定腳本 如果只是單一腳本檔要指定使用特定版本的 Python, 可以仿照 Linux 系統在腳本檔內的第一行加上 shebang 行, 例如目前環境如下: ```shell # py -0p -V:3.12 C:\Users\meebo\AppData\Local\Programs\Python\Python312\python.exe -V:3.11 C:\Users\meebo\AppData\Local\Programs\Python\Python311\python.exe -V:3.9 * C:\Users\meebo\AppData\Local\Programs\Python\Python39\python.exe ``` 我們可以在 shebang 行指定以 3.11 版的 Python 執行 test.py: ```shell # cat test.py #! /usr/bin/python3.11 import sys print(sys.version) # py test.py 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] ``` 這裡的 "/usr/bin/python" 路徑當然不存在 Windows 上, Python Launcher 將之視為用來指定 Python 版本的虛擬指令, 這樣的作法是可以讓 shebang 和 Linux 環境相容。除了使用 "/usr/bin/python" 外, 也可以使用 "/usr/local/bin/python" 這個 Linux 上 Python 符號連結檔常會放置的地方, 或者單純的 "python"。 如果改把 test.py 改成這樣, 執行的就會是 Python 3.12: ```shell # cat test.py #! /usr/bin/python3.12 import sys print(sys.version) # py test.py 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] ``` 如果沒有完整指定版本, 就會以相符的版本中最新的版本執行, 例如: ```shell # cat test.py #! /usr/bin/python3 import sys print(sys.version)  meebo on  ~/code/python # py test.py 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] ``` 這裡只指定了 3. 所以會以 3.12 執行。 你也可以直接標記執行檔路徑, 例如: ```shell # cat test.py #! C:\Users\meebo\AppData\Local\Programs\Python\Python312\python.exe import sys print(sys.version) # py test.py 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] ``` 這樣就會以指定路徑的 Python 執行腳本, 而不會使用預設的版本了。 ### 搭配虛擬環境 如果有啟用[虛擬環境](/gOmzsLQRQtmyrpx8j8Z7iA), 不指定版本時就會執行虛擬環境設定的 Python, 例如: ```shell! # py Python 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z # .\venv\work\Scripts\activate # py Python 3.11.6 (tags/v3.11.6:8b6ee5b, Oct 2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> ^Z ``` ## 跨平台的 Python 版本管理方法--pyenv Python Launcher 雖然簡單好用, 卻有以下缺點: - 不能跨平台, 只有 Windows 可用。 - 無法安裝同一個大版本下的不種次版本, 例如無法同時安裝 3.11.5 和 3.11.3。 這一節我們介紹一套可以跨平台又有極大彈性的工具 -- pyenv。 ## 安裝 pyenv [pyenv](https://github.com/pyenv/pyenv) 是為 Linux 系統設計的工具, 雖然並沒有正式的 Windows 版, 不過有善心人士將這個工具移植到 [Windows 版](https://github.com/pyenv-win/pyenv-win), 所以也算是可以跨平台。各平台安裝方式如下: - Windows 可使用 PowerShell 腳本安裝: ```powershell Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1" ``` :::info 你也可以透過 scoop 軟體管理工具安裝 pyenv, 不過因為 scoop 的運作方式會和安裝 msi 檔的 msiexec 工具不合, 必須修改 pyenv 的程式檔, 請參考〈[解決透過 scoop 安裝的 pyenv 無法正常運作的問題](/P2mmrkd2QVSAyAXMt_BqtQ)〉一文。 ::: - Mac 可使用 brew 套件管理工具安裝: ```sh brew update brew install pyenv ``` - Linux 可以用 bash 腳本安裝: ```sh curl https://pyenv.run | bash ``` ### 設定環境變數 Windows 版安裝會自動設定環境變數, 不需要額外動作。 Linux/Mac 請務必根據你使用的 shell 依照以下步驟設定環境變數: - Linux 預設的 bash:請在你的 .bashrc 檔中加入: ```sh export PYENV_ROOT="$HOME/.pyenv" command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" ``` - Mac 預設的 zsh:請在 .zsh 檔中加入: ```sh export PYENV_ROOT="$HOME/.pyenv" [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" ``` 如果你使用的是其他 shell, 請參考[官網上的說明](https://github.com/pyenv/pyenv/blob/master/README.md#set-up-your-shell-environment-for-pyenv)。 修改好設定檔後, 請記得重新開啟 shell, 讓設定生效。 ### 設定開發工具 由於 Linux/Mac 上的 Python 可能採用原始碼形式發布, 安裝時可能會需要編譯, 因此也請依照[官網上的說明](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)預先安裝所需的各項開發套件, 才不會安裝失敗。 ## 安裝特定版本的 Python 你可以先使用以下指令列出可安裝的 Python 版本, 這是 Windows 的結果: ```powershell # pyenv install -l :: [Info] :: Mirror: https://www.python.org/ftp/python 2.4-win32 2.4.1-win32 ... 3.0a1-win32 3.0a1 3.0a2 ... 3.13.0a2-win32 3.13.0a2 ``` 你可以看到從 2.X 到 3.X 版一應俱全。以下則是 Linux 的結果: ```shell $ pyenv install -l Available versions: 2.1.3 2.2.3 ... 3.0.1 3.1.0 ... activepython-2.7.14 activepython-3.5.4 activepython-3.6.0 anaconda-1.4.0 ... stackless-3.5.4 stackless-3.7.5 ``` 你可以看到在 Linux 上除了官方版本外, 還包含了協力廠商開發的版本, 你可以自己挑選想用的版本。 要安裝特定的版本, 就依照剛剛看到的版本名稱即可, 例如若要嘗鮮安裝 3.13.0a2 這個 alpha 版本, 就如下指令: ```powershell # pyenv install 3.13.0a2 :: [Info] :: Mirror: https://www.python.org/ftp/python :: [Downloading] :: 3.13.0a2 ... :: [Downloading] :: From https://www.python.org/ftp/python/3.13.0/python-3.13.0a2-amd64.exe :: [Downloading] :: To C:\Users\meebo\.pyenv\pyenv-win\install_cache\python-3.13.0a2-amd64.exe :: [Installing] :: 3.13.0a2 ... :: [Info] :: completed! 3.13.0a2 ``` 這樣就安裝完畢了。pyenv 會將所有的 Python 都安裝到統一的資料夾下: - Windows 為使用者資料夾下的 .pyenv\pyenv-win\versions\, 例如: ``` # ls .\.pyenv\pyenv-win\versions\ Directory: C:\Users\meebo\.pyenv\pyenv-win\versions Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 2024/1/6 下午 01:47 3.10.8 d---- 2024/1/4 下午 08:07 3.12.1 d---- 2024/1/6 下午 04:57 3.13.0a2 ``` 表示我已經安裝了 3 種版本。 - Linux/Mac 為使用者資料夾下的 .pyenv/versions: ```sh $ ls .pyenv/versions 3.10.13 3.12.0 ``` 表示我已經安裝了 2 種版本。 這些經由 pyenv 安裝的 Python 都是獨立的, 不會和系統安裝的 Python 打架。 你可以使用以下指令查看目前安裝的版本: ```shell $ pyenv versions * system (set by /home/meebox/.pyenv/version) 3.10.13 3.12.0 ``` 其中 `system` 表示系統原本就安裝的 Python。 ### 移除特定版本 如果要移除已經安裝的 Python 版本, 可以如下指令完成: ```shell # pyenv uninstall 3.13.0a2 pyenv: Successfully uninstalled 3.13.0a2 # pyenv versions 3.10.8 * 3.12.1 (set by %PYENV_VERSION%) ``` ## 切換要使用的 Python 版本 安裝好需要的 Python 版本後, 最重要的事情就是能夠自由切換不同的版本, 切換的方式有以下幾種: - `pyenv shell 版本名稱`:這會讓當前 shell 採用指定版本的 Python, 關閉 shell 之後就失效了。 - `pyenv local 版本名稱`:這會讓當前路徑採用指定版本的 Python, 只要切換到這個路徑下, 就會生效, 離開此路徑就會失效。 - `pyenv global 版本名稱`:這會在沒有利用上述方式設定版本時採用指定的版本。 這三種方式越前面的越優先, 舉例來說, 我的系統上預設的 Python 版本如下: ```shell $ python3 Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux ``` 如果下達以下指令設定當前 shell 採用 3.12.0 版: ```shell $ pyenv shell 3.12.0 $ python3 Python 3.12.0 (main, Jan 6 2024, 14:34:15) [GCC 12.2.0] on linux ``` 你會看到立刻更改成指定版本了。如果切換到特定資料夾, 下達指令: ```shell $ cd code/python/test1 $ pyenv local 3.10.13 $ python3 Python 3.12.0 (main, Jan 6 2024, 14:34:15) [GCC 12.2.0] on linux ``` 雖然指定該資料夾要改用 3.10.13, 但因為 `pyenv shell` 的設定是第一優先, 所以執行的還是之前設定的 3.12.0 版。 如果我們退出 shell 再重新啟動 shell, 那麼 `pyenv shell` 的設定就會失效, 切換到同一個資料夾時, 就會看到執行的 Python 版本也跟著變化了: ```shell $ cd code/python/test1 $ python3 Python 3.10.13 (main, Oct 16 2023, 19:02:46) [GCC 12.2.0] on linux ``` 現在的確是 3.10.13 版了。由於現在我們位在有指定版本的路徑下, 如果以 `pyenv global` 指定版本, 還是會使用優先權較高的資料夾版本: ```shell $ pwd /home/meebox/code/python/test1 $ pyenv global 3.12.0 $ python3 Python 3.10.13 (main, Oct 16 2023, 19:02:46) [GCC 12.2.0] on linux ``` 如果離開這個資料夾, 就會執行剛剛設定的 3.12.0 了: ```shell $ cd $ pwd /home/meebox $ python3 Python 3.12.0 (main, Jan 6 2024, 14:34:15) [GCC 12.2.0] on linux ``` ### 查詢目前設定的版本 只要使用設定版本時相同的指令, 但是不加上版本參數, 就可以查詢目前設定的版本: ```shell $ pwd /home/meebox/code/python/test1 $ pyenv global 3.12.0 $ pyenv local 3.10.13 $ pyenv shell pyenv: no shell-specific version configured ``` 由於剛剛已經離開了下達 `pyenv shell` 的 shell, 所以它會告訴我們並沒有設定當前 shell 要使用的 Python 版本。 ### 查詢目前使用的版本 你也可以透過指令查詢目前會使用的 Python 版本以及是透過哪一個設定決定使用此版本, 例如: ```shell $ pwd /home/meebox/code/python/test1 $ pyenv version 3.10.13 (set by /home/meebox/code/python/test1/.python-version) ``` 由於進入了使用 `pyenv local` 設定過特定版本的路徑, 所以它會告訴我們是透過該資料夾的內的設定檔 `.python-version` 決定版本。你可以查看該路徑中的設定檔: ```shell $ cat .python-version 3.10.13 ``` 就可以看到其實 `pyenv local` 會把指定版本名稱記錄在這個檔案中。 如果我們離開此路徑, 重新檢視版本: ```shell $ pwd /home/meebox $ pyenv version 3.12.0 (set by /home/meebox/.pyenv/version) ``` 就會發現這個路徑本身沒有設定版本, 所以採用的是 `pyenv global` 指定設定的版本, 這個版本資訊會記錄在使用者資料夾下 `.pyenv/version` 檔中: ```shell $ cat .pyenv/version 3.12.0 ``` 在 Windows 系統上, `pyenv global` 設定檔的位置稍有不同: ```shell # pyenv version 3.12.1 (set by C:\Users\meebo\.pyenv\pyenv-win\version) ``` 如果下達 `pyenv shell` 指令再查看: ```shell $ pyenv shell 3.12.0 $ cd code/python/test1 $ pyenv version 3.12.0 (set by PYENV_VERSION environment variable) ``` 就會看到不論在哪裡, 都會採用 `pyenv shell` 指定的版本, 而且這個設定是記錄在 `PYENV_VERSION` 環境變數中: ```shell $ echo $PYENV_VERSION 3.12.0 ``` 在 Windows 下也是一樣: ```shell # pyenv shell 3.12.1 # pyenv version 3.12.1 (set by %PYENV_VERSION%) # cat Env:\PYENV_VERSION 3.12.1 ``` 如果只是想要知道採用的版本, 並不需要顯示設定檔的位置, 可以下達 `pyenv version-name`: ```shell # pyenv version-name 3.12.1 ``` ### 移除設定 如果要移除指定版本的設定, 在 Linux 上可以使用 `system` 做為版本名稱,即可變更回使用原本系統的 Python。例如以下是預設為 2.7.18 版本的環境: ```shell $ python Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 19 2020, 20:48:48) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> ``` 下達以下指令設定目前 shell 要使用 3.12.0 版本: ```shell $ pyenv shell 3.12.0 $ python Python 3.12.0 (main, Jan 8 2024, 11:13:10) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> ``` 如果要取消設定變回系統的 Python, 只要下達 `pyenv shell system` 指令即可: ```shell $ pyenv shell system $ python Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 19 2020, 20:48:48) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> ``` 馬上就變回原本預設的 2.7.18 了。 :::warning 在 WSL 上, 因為整合 Windows 的關係, 指定版本名稱 'system' 會出現錯誤訊息: ```shell! $ pyenv shell system pyenv: version `system' not installed ``` 請依照 Windows 平台的方式刪除設定檔。 ::: 你也可以使用 `--unset` 子命令移除設定, 例如以下先設定改用 3.12.0 版: ```shell $ pyenv shell 3.12.0 $ python Python 3.12.0 (main, Jan 6 2024, 14:34:15) [GCC 12.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> ``` 只要下達 `pyenv shell --unset` 命令, 就可以移除剛剛的設定: ```shell $ pyenv shell --unset $ python Python 2.7.18 (default, Jan 10 2024, 10:21:11) [GCC 12.2.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. ``` 又回到原本的 2.7.17 了。 Windows 上沒有 `system` 這個版本編號, 必須使用 '--unset' 子命令的方式移除設定。 你也可以暴力刪除之前使用 `pyenv version` 查到的設定檔或是環境變數, 這樣就會解除設定。 ## 注意事項 使用 pyenv 並不會建立虛擬環境, 所以如果在兩個不同的資料夾設定使用同一個版本的 Python, 它們的 Python 環境就是共用的, 例如: ```shell $ pwd /home/meebox/code/python/test1 meebox at meebox in ~/code/python/test1 $ pyenv version 3.10.13 (set by /home/meebox/code/python/test1/.python-version) meebox at meebox in ~/code/python/test1 $ pip list Package Version ---------- ------- pip 23.0.1 setuptools 65.5.0 ``` 如果建立另外一個資料夾 test2, 設定同樣的 Python 版本: ```shell! $ pwd /home/meebox/code/python/test2 meebox at meebox in ~/code/python/test2 $ pyenv local 3.10.13 meebox at meebox in ~/code/python/test2 $ pip list Package Version ---------- ------- pip 23.0.1 setuptools 65.5.0 ``` 在 test2 中安裝任何套件, 在 test1 中也一樣會生效, 因為它們是同一個 Python 環境: ```shell! $ pip install rich Collecting rich ... $ pip list Package Version -------------- ------- markdown-it-py 3.0.0 mdurl 0.1.2 pip 23.0.1 Pygments 2.17.2 rich 13.7.0 setuptools 65.5.0 ``` 切換到原本的 test1 路徑下, 就會看到剛剛在 test2 資料夾下安裝的套件: ```shell! $ cd ../test1 $ pip list Package Version -------------- ------- markdown-it-py 3.0.0 mdurl 0.1.2 pip 23.0.1 Pygments 2.17.2 rich 13.7.0 setuptools 65.5.0 ``` 也就是說 pyenv 只能幫助你切換 Python 版本, 但如果是希望有獨立的 Python 環境, 就要在搭配建立[Python 虛擬環境--venv](/gOmzsLQRQtmyrpx8j8Z7iA)才行。 ## pyenv 的運作原理 pyenv 的基本運作原理就是在 `.pyenv` (Windows 平台則是在 `.pyenv/pyenv-win`) 下建立了一個 shims 資料夾, 裡面有跟 Python 執行檔同名的檔案。 pyenv 會將這個 shims 路徑放在 PATH 環境變數的前面, 擁有較高的優先權, 因此當你執行 python 時, 實際上執行的是 shims 下的 python, 這個 python 在依照個別設定檔案判斷要執行的是哪一個版本的 Python。 由於有這個 shim 資料夾下的執行檔當成中介 (shim 原意是墊片, 作為兩個東西接合的緩衝, 但在 pyenv 的情境下, 其實比較適合稱為『中介』或是『轉介』), 就可以彈性接換 Python 版本了。