LoginSignup
110
103

More than 5 years have passed since last update.

【Python】さようなら仮想環境?

Posted at

Mediumで以下のような記事があった

Goodbye Virtual Environments? – Chad Smith – Medium

さようなら、仮想環境?

記事を見る感じ、python と pip の代わりになるようなコマンドっぽい

また、PEP582で提案されている__pypackages__が使われている


ソースコードを見たり、READMEを見たり、Medinumを見たりしただけなので、間違いがあるかもしれません。
間違いがありましたら、教えていただけると嬉しいです。

動作環境

Python 3.7.1

pythonloc

cs01/pythonloc

pythonとpipを使って実装されている小さなプロジェクト

仮想環境がいらなくなりそうな予感!?

pythonlocのコマンド

以下のコマンドと対応している

通常 pythonlocを使うと...
$ python $ pythonloc
$ pip $ piploc
$ pip freeze > requirements.txt $ pipfreezeloc > requirements.txt

piplocコマンド

pipの代わり

$ piploc install {pkg}

./__pypackages__/{version}/lib内にpkgがインストールされる

pipでのインストール先が./__pypackages__/{version}/libとなる

pythonlocコマンド

pythonの代わり

$ pythonloc

PYTHONPATHに、.:__pypackages__/{version}/lib:$PYTHONPATHを設定された状態で、python(sys.executable)が実行される

pipfreezelocコマンド

pip freezeの代わり

$ pipfreezeloc

。・__pypackages__/{version}/lib内のパッケージの情報を出力する

pythonlocの何がすごいと思ったのか

pipenv shellみたいに仮想環境の有効化をしなくてもよくなる

これは、モジュールの検索順序の仕組みを利用してうまく実装されている

まず、Pythonはモジュールのインポートをするときに、インポートするモジュールをsys.pathから検索する。

このsys.pathについての説明は、ドキュメントに書いてあった

spam という名前のモジュールをインポートするとき、インタープリターはまずその名前のビルトインモジュールを探します。見つからなかった場合は、 spam.py という名前のファイルを sys.path にあるディレクトリのリストから探します。 sys.path は以下の場所に初期化されます:

・入力されたスクリプトのあるディレクトリ (あるいはファイルが指定されなかったときはカレントディレクトリ)。
・PYTHONPATH (ディレクトリ名のリスト。シェル変数の PATH と同じ構文)。
・インストールごとのデフォルト。

pythonlocでは、PYTHONPATH.:__pypackages__/{version}/lib:$PYTHONPATHを設定することによって、優先的に検索しに行くようにしている

PYTHONPATHに.:__pypackages__/{version}/lib:$PYTHONPATHを設定している

PYTHONPATHについては、ドキュメントを参照

まず、通常のpythonの場合

$ python
>>> import sys, os, pprint

>>> os.environ.get('PYTHONPATH', '')
''

>>> pprint.pprint(sys.path)
['',
 'temp/test/pythonloc',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python37.zip',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python3.7',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python3.7/lib-dynload',
 '/Users/tamago324/.local/lib/python3.7/site-packages',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python3.7/site-packages']

次に、pythonlocの場合


$ pythonloc
>>> import sys, os, pprint

>>> os.environ.get('PYTHONPATH', '')
'.:__pypackages__/3.7/lib:'

>>> pprint.pprint(sys.path)
['',
 '/temp/test/pythonloc',
 # ここに追加されている
 '/Users/tamago324/src/python/test/pythonloc/__pypackages__/3.7/lib',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python37.zip',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python3.7',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python3.7/lib-dynload',
 '/Users/tamago324/.local/lib/python3.7/site-packages',
 '/Users/tamago324/.pyenv/versions/3.7.1/lib/python3.7/site-packages']

このように、__pypackages__/{version}/libは、/Users/tamago324/.pyenv/versions/3.7.1/lib/python3.7/site-packagesよりも前にあるため、__pypackages__/{version}/libが優先的に検索されるようになる

まとめ

pythonlocの考え方すごい。__pypackages__すごい。PEP582すごい。

参考文献

110
103
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
110
103