Pythonランチャーで複数のPython環境を使い分ける

コンピューターPython,プログラミング,超長い記事(4000字以上)

Pythonは、使用するライブラリによって対応するPythonのバージョンが異なる場合があるため、複数のバージョンのPythonをインストールすることがあります。

通常、コマンドプロンプトからPythonを起動しようとすると、パスが通っている最初のpython.exeが起動してしまいます。もちろん、その時々でパスを書き換えたり、フルパス指定したりすれば希望のバージョンのPythonを起動できますが、面倒です。

こういう場合に、Pythonの公式が用意している、Windows環境向けのPython切り替えソフト「Pythonランチャー(py.exe)」が便利ですので紹介します。

本編の前に・・・

この記事は、自分用の覚えとして作成しているものです。これらのページを参考にさせていただきました。この記事よりこれらのウェブサイトの方が分かりやすいと思います。

Pythonランチャー(py.exe)とは

Pythonランチャーは、Pythonの公式がWindows環境向けにリリースしているソフトです。複数のバージョンのPythonをインストールしている環境でも、任意のバージョンを指定してPythonインタープリターを起動したり、Pythonスクリプトを実行させたりできます。ここで言う「バージョン」とは、同じメジャーバージョン・マイナーバージョンの「64ビット版/32ビット版」の違いも含みます。

Python 3.3以降、Pythonをデフォルト設定でインストールすると、Pythonランチャーも一緒にインストールされます。

Pythonランチャーの実体はC:\Windows\py.exeです。拡張子.pyなども、Pythonランチャー py.exeに関連付けされます。

通常、Pythonインタープリターを使用する場合は、コマンドプロンプトに「python」と入力して、パスの通っているpython.exeを起動すると思います。Pythonランチャーをインストールしている環境では、python.exeにパスを通す必要はありません。インタープリターの起動も、スクリプトの実行もpy.exe経由で行います。

ちなみにPython 2系をインストールする際、デフォルトで「.pyファイルの関連付けを行う」の設定がオンになっています。これだとPythonランチャーへの関連付けが外れてしまいますので、オフに変更してインストールしてください。

Pythonランチャーの使い方

コマンドプロンプトを開いて、py --helpと入力すると、Pythonランチャーの使い方が表示されます。

C:\>py --help

Python Launcher for Windows Version 3.8.4150.1013

usage:
py [launcher-args] [python-args] script [script-args]

Launcher arguments:

-2     : Launch the latest Python 2.x version
-3     : Launch the latest Python 3.x version
-X.Y   : Launch the specified Python version
     The above all default to 64 bit if a matching 64 bit python is present.
-X.Y-32: Launch the specified 32bit Python version
-X-32  : Launch the latest 32bit Python X version
-X.Y-64: Launch the specified 64bit Python version
-X-64  : Launch the latest 64bit Python X version
-0  --list       : List the available pythons
-0p --list-paths : List with paths

(以下、python.exeのヘルプが続きますが、省略)

usageを訳すと、こんな感じだと思います。XやYには、起動したいバージョンを数値で指定します。後の項で、より具体的な使用方法を説明します。

使い方:
py [Pythonランチャー引数] [Python(python.exe)引数] スクリプトのパス [スクリプト引数]

Pythonランチャー引数:

-2     : Python 2.x系の最新版を起動する
-3     : Python 3.x系の最新版を起動する
-X.Y   : 指定したバージョンのPythonを起動する
     上記は、適合する64bit版Pythonがあれば、基本的に64bit版を起動します。
-X.Y-32: 指定したバージョンの32bit版Pythonを起動する
-X-32  : Python X系の32bit版Pythonを起動する
-X.Y-64: 指定したバージョンの64bit版Pythonを起動する
-X-64  : Python X系の64bit版Pythonを起動する
-0  --list       : 利用可能なPythonバージョンのリストを表示する
-0p --list-paths : 利用可能なPythonバージョンとパスのリストを表示する

インストール済みのPython一覧を表示するには

インストール済みのPython環境の一覧を表示するには、py -0p(←ゼロ・ピー)やpy --list-pathsを実行します(パスも表示する場合)。

C:\>py -0p
Installed Pythons found by py Launcher for Windows
 -3.8-64        C:\Users\ユーザー名\AppData\Local\Programs\Python\Python38\python.exe *
 -3.8-32        C:\Users\ユーザー名\AppData\Local\Programs\Python\Python38-32\python.exe
 -3.7-64        C:\Users\ユーザー名\AppData\Local\Programs\Python\Python37\python.exe
 -3.7-32        C:\Users\ユーザー名\AppData\Local\Programs\Python\Python37-32\python.exe
 -2.7-32        C:\Users\ユーザー名\AppData\Local\Programs\Python\Python27\python.exe

上記の例では、5つのバージョン(32bit/64bitの違いを含む)のPythonがインストールされていることが分かります。-3.8-64の末尾にアスタリスクが付いていますが、これはデフォルトで起動するバージョンであることを示します。

Pythonインタープリターを起動するには

通常、Pythonインタープリターを起動する場合は、コマンドプロンプトなどでpythonと入力して起動すると思います。対して、Pythonランチャーをインストールしている環境ではpyと入力すれば起動します。

C:\>py
Python 3.8.4 (tags/v3.8.4:dfa645a, Jul 13 2020, 16:46:45) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

前述の通り、私の環境ではPython 3.8の64bitがデフォルトになっていますので、それが起動しました。

同様に、-3.7を指定すると、3.7(の64bit版)が起動します:

C:\>py -3.7
Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

また、-3-32を指定すると、3系で32bitの最新版である3.8 32bitが起動します:

C:\>py -3-32
Python 3.8.4 (tags/v3.8.4:dfa645a, Jul 13 2020, 16:30:28) [MSC v.1926 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

-2と指定すれば、2系の最新版が起動します(今回の例の場合、2系は2.7 32bitしか入れていませんので、それが起動しました):

C:\>py -2
Python 2.7.17 (v2.7.17:c2f86d86e6, Oct 19 2019, 20:49:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

ちなみに、インストールしていないバージョンを指定すると、「インストールされていない」とエラーになります。

C:\>py -2-64
Python 2-64 not found!
Installed Pythons found by py Launcher for Windows
 -3.8-64 *
 -3.8-32
 -3.7-64
 -3.7-32
 -2.7-32

Requested Python version (2-64) not installed, use -0 for available pythons

また、Pythonランチャーの引数に続いてスクリプトのパスを指定すると、そのスクリプトが実行されます。その際、後述のシェバンよりも、こちらのPythonランチャー引数の方が優先されます。

スクリプトごとにPythonバージョンを指定するには

シェバンを使ったバージョンの指定

Pythonスクリプトを作成して、関連付けに基づいて実行すると、基本的にはデフォルトのPythonで実行されます(今回の例では3.8.4 64bit)。

ただ、スクリプトごとに使用しているライブラリが異なって、使いたいバージョンも違うかもしれません。そのような場合には、スクリプトのシェバンでPythonのバージョンを指定します。(シェバンとは、スクリプトの1行目に書くもので、そのスクリプトの実行環境を指定するものです。Unix系OSのシェルスクリプトなどでも指定します。頭に書く#!の英語圏での読み「hash bang」から省略して「shebang」と呼ぶようになったらしい)

試しに、このようなスクリプトを用意してみます。このスクリプトは、単に実行中のPythonのバージョンを表示するだけのものです。(Pythonの公式ヘルプから引用)

#!python
import sys
sys.stdout.write("hello from Python %s\n" % (sys.version,))

Pythonランチャーにスクリプトパスを渡すと、スクリプトを実行できます。すると次のような出力が帰ってきます。(Pythonランチャーをインストールしている環境では、拡張子.pyはPythonランチャーに関連付けられていますので、ファイル名だけ指定したり、ダブルクリックした場合でも同様の挙動を示します)

C:\>py sample.py
hello from Python 2.7.17 (v2.7.17:c2f86d86e6, Oct 19 2019, 20:49:36) [MSC v.1500 32 bit (Intel)]

Python 2系で実行されました。インタープリターを起動する際、単にpyと打った場合はPython 3系の最新64bit版が起動しましたが、それと対照的です。これは、Linuxなどの環境では、pythonコマンドはPython 2系を、python3コマンドはPython 3系を表すことが多いため、Linuxなどとの互換性からこのような仕様になっているようです。

なので、シェバンを#!python3に書き換えると、Python 3系の最新版で実行されます:

C:\>sample.py
hello from Python 3.8.4 (tags/v3.8.4:dfa645a, Jul 13 2020, 16:46:45) [MSC v.1924 64 bit (AMD64)]

同様に、シェバンを#!python3.7に書き換えると、3.7の64bit版で実行されます:

C:\>sample.py
hello from Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)]

シェバンを#!python3-32に書き換えると、3系32bit版の最新で実行されます:

C:\>sample.py
hello from Python 3.8.4 (tags/v3.8.4:dfa645a, Jul 13 2020, 16:30:28) [MSC v.1926 32 bit (Intel)]

ちなみに、シェバンをタイプミスして#!pyhton3と入力すると、起動しません:

C:\>sample.py
Unable to create process using 'pyhton3 "C:\sample.py" '

また、シェバンの行を削除すると、インタープリター起動時と同様、デフォルトバージョン(最新の64bit)で実行されます:

C:\>sample.py
hello from Python 3.8.4 (tags/v3.8.4:dfa645a, Jul 13 2020, 16:46:45) [MSC v.1924 64 bit (AMD64)]

さらに、インストールしていないバージョンを指定して、シェバンに#!python2-64と書くと、「インストールされてない」とエラーとなります:

C:\>sample.py
Requested Python version (2-64) is not installed

Linuxなどへの移植性を考えたシェバンの書き方

ところで、シェバンは元々Unix系OSのシェルスクリプトで使われてきたと書きました。Pythonスクリプトも同様で、Unix系OSではシェバンで指定されたPythonで実行されます。

Linuxなどへの移植性を考えると、Linuxで実行するためのシェバン、例えば#!/usr/bin/python3.7などを指定したいかもしれません。

その場合は、Linuxを想定したPython実行ファイルのパスを指定してあげればOKです。例えば、

#!/usr/bin/python3.7
import sys
sys.stdout.write("hello from Python %s\n" % (sys.version,))

というようにシェバンを書いて実行すると、予想通り3.7の64bit版で実行されます:

C:\>sample.py
hello from Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)]

これは、PythonランチャーがLinux風のシェバンも読み取って、適切なバージョンで実行してくれるからのようです。

ビット数まで指定する場合は、シェバンを#!/usr/bin/python3.7-32とすればOKです:

C:\>sample.py
hello from Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 07:55:33) [MSC v.1916 32 bit (Intel)]

ただし、ビット数まで指定したシェバンでは、Linux側ではうまく実行できないと思いますので、おすすめしません。

ここまでをまとめると、特に理由がない限り、シェバンは#!/usr/bin/python3を指定するのがよいのではないかと思います。(WindowsならPython 3系の最新版で、Linuxではシステムにインストールされている/usr/bin/python3で実行してくれる。単に#!python3でも大丈夫かもしれない)

このあたりに関しては、公式ヘルプのこちらの部分に説明があります。

シェバンより、Pythonランチャー引数が優先される

スクリプト中にシェバンを書いても、実行する際、Pythonランチャーにバージョンを指定する引数を与えた場合は、そちらが優先されます。

例えば、このようなスクリプトを用意します:

#!/usr/bin/python3.7-32
import sys
sys.stdout.write("hello from Python %s\n" % (sys.version,))

実行する際、単にPythonランチャーにスクリプトパスを与えると、シェバンに書かれているバージョンで実行されます:

C:\>py sample.py
hello from Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 07:55:33) [MSC v.1916 32 bit (Intel)]

インタープリター起動時と同じように、バージョンを指定する引数を与えると、引数の方が優先されます:

C:\>py -2 sample.py
hello from Python 2.7.17 (v2.7.17:c2f86d86e6, Oct 19 2019, 20:49:36) [MSC v.1500 32 bit (Intel)]

pipを使用するには

Pythonのパッケージマネージャーであるpipを利用する際は、注意が必要です。というのも、複数のバージョンのPython環境がインストールされていますので、「どのバージョンのPython環境にインストールするか」を指定してあげないといけません。

デフォルトバージョンのPython環境にnumpyをインストールする場合は、py -m pip install numpyというように、バージョンを指定せずにpipコマンドを実行すればOKです。この場合、-m以降の引数は、python.exeに対して与える引数として扱われます。

C:\>py -m pip install numpy
Collecting numpy
  Downloading numpy-1.19.0-cp38-cp38-win_amd64.whl (13.0 MB)
     |████████████████████████████████| 13.0 MB 3.3 MB/s
Installing collected packages: numpy
  WARNING: The script f2py.exe is installed in 'C:\Users\ユーザー名\AppData\Local\Programs\Python\Python38\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed numpy-1.19.0

パスが通っていない、と警告が出ていますが、無視してよいでしょう。

対して、古いバージョンの環境にパッケージを足す場合は、バージョンを指定する引数を追加し、py -3.7-32 -m pip install numpyとします。このとき、-3.7-32の部分はPythonランチャーに対する引数で、-m以降はpython.exeに対する引数として扱われます。

C:\>py -3.7-32 -m pip install numpy
Collecting numpy
  Downloading numpy-1.19.0-cp37-cp37m-win32.whl (10.9 MB)
     |████████████████████████████████| 10.9 MB 6.4 MB/s
Installing collected packages: numpy
  WARNING: The script f2py.exe is installed in 'C:\Users\ユーザー名\AppData\Local\Programs\Python\Python37-32\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed numpy-1.19.0

まとめ

軽い覚え書き記事として書き始めたら、すごい重量級の記事になってしまいました。

簡単にまとめると、下記の通りです。

インタープリターの起動

コマンドプロンプト上で下記の通り、コマンドを実行する。

最新版でPythonインタープリターを起動:
py

指定したバージョンでPythonインタープリターを起動(64bitなら、ビット数は省略可):
py -3.7-32

シェバンを無視してバージョンを指定してスクリプトを実行:
py -3.7 script.py

スクリプトのシェバンに指定

スクリプト1行目のシェバンに下記の通り記載すれば、(実行時にバージョンを指定しない限り)シェバンに書かれたバージョンのPythonで実行される。

最新版のPythonで実行:
#!python3
注意:「python」としてしまうと、Python 2系で実行されてしまうので気をつける

指定したバージョンのPythonで実行:
#!python3.7-32

Linuxなどへの移植を考えて、Linux環境でのフルパスで指定:
#!/usr/bin/python3

同じく、特定のバージョンを指定:
#!/usr/bin/python3.7
注意:Windows向けであればビット数指定もできるが、おそらくLinux側では動かない

pipでパッケージを追加

コマンドプロンプトで下記のコマンドを実行する。(例として、numpyをインストール)

最新版のPython環境にパッケージを追加:
py -m pip install numpy

指定したバージョンのPython環境にパッケージを追加:
py -3.7-32 -m pip install numpy