bashなどでスクリプトを実行するときには1行目に#!でこのスクリプトを実行すべきコマンドを書いておいたりする。その際、複数のバージョンのPythonが入ってる環境だと単に./hoge.py
というコマンドでPythonを起動するとどのバージョンが起動されたかわからない。という訳でまずは以下。
import sys
print(sys.version)
これで起動されているPythonのバージョンがわかります。そんなにいうことはない。
出力例はこんな感じ。
λ version.py
3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
Cmderでは1行目が認識される
ここから本題。Cmderというコンソールエミュレータではbashライクに./something.py
というコマンドで、もしくは./
無しでもインタプリタが起動できる。(いまどきPythonのことをインタプリタといっている人どのくらいいるんだろうか。)さらに1行目の#!
アノテーションも正しく認識してくれる。無ければ勝手に.py
に反応してPythonを起動する模様。
バージョンの切り替えテスト
同じく以下のファイルがversion.pyという名前で保存されているとします。今度は#!
があります。
#!python
import sys
print(sys.version)
これに対してCmderでcmd.exeをホストしている際の挙動がこちら。
λ version.py
3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
pythonに対してPATHは通っていますがcmd.exeだけの場合は少なくともpython version.py
が必要でした。cmd.exeだけではこんな機能は無いはずなんですけど勝手にpython3.8.0が起動されています。これはおそらくCmderの機能です。もういちど言っておくと#!python
を書かなくても.py
に反応して勝手にPythonが起動します。
PowerShellならともかくcmdのアップデートはもうないはずなので実はcmd単体の機能で出来てたってことは無いでしょう。 というわけで特定のコードだけは3.7.x系で動かしたい場合、次のようなことが可能です。
#!python3.7
import sys
print(sys.version)
これに対する出力例はこちら。
λ python3.7 --version
'python3.7' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
λ version.py
3.7.5 (tags/v3.7.5:5c02a39a0b, Oct 15 2019, 00:11:34) [MSC v.1916 64 bit (AMD64)]
python3.7というコマンドにはPATHが通っていないのにちゃんと3.7.x系が起動されました。不思議ですねぇ。試しに無いコマンド、例えば#!pythen
というパイセンコマンドで起動しようとして見る、などするとだいたい何をしているかどうかがわかってきます。おそらくですけど有名なスクリプトの拡張子が来たらそのままcmdには渡さずCmderのホスト側でプロセスを生成しようと試みるようです。その際、きちんとバージョン部分もパースされてます。なのでこういう切り替えが可能なんですねぇ。
適当に試した結果がこちら
λ version.py
Unable to create process using 'pythen "C:\Users\TM23\Documents\Python\lab4\version.py" '
λ version.py
Requested Python version (2) is not installed
λ version.py
Requested Python version (0) is not installed
λ version.py
Requested Python version (4) is not installed
λ version.py
Requested Python version (3.6) is not installed
3.6.x系は消してるんでね。
結論
Cmder便利。