設定 Python Launcher 預設的 Python 版本
Tags: python
Published: 2024-01-18 05:44:44

在 Windows 中, 你可以使用 Python Launcher 選用不同版本的 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)
```

目前預設就是最新的 3.12, 如果直接執行 py 就會看到實際的結果：

```shell
# py
Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 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.0：

```shell
# py
Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 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.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 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.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)]
```

如果沒有完整指定版本, 就會以相符的版本中最新的版本執行, 例如：

```shell
# cat test.py
#! /usr/bin/python3
import sys
print(sys.version)
 meebo on  ~/code/python
# py test.py
3.12.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 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.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)]
```

這樣就會以指定路徑的 Python 執行腳本, 而不會使用預設的版本了。

## 結語

Python Launcher 是個很好用的工具, 不過如果沒有弄懂他找尋版本的邏輯, 就可能會錯用版本, 導致程式無法正常運作了。