pyenvからpipenvにしてみた

python環境構築の見直し

pythonのライブラリ管理と仮想環境の構築のためにpyenv``pyenv-virtualenv``anacondaを用いているのですが、まだまだ初心者の私にとっては複雑で「なぜこのツールをインストールしているんだろう」と役割が分かっていない部分もあります
又、anacondaを導入することで様々なライブラリやツールが利用可能になりますが、現状宝の持ち腐れ状態なので必要なモノだけ導入し、今後入れたいと思ったモノについても1つずつ導入していくスタイルが私に合っているかなと思いました

そこでPython環境の再構築を視野に入れて調べていたところ、ライブラリ管理仮想環境構築の二役を一手に担っているパッケージ管理ツールPipenvを見つけました

ドキュメントを見ていると導入・管理・運用の全てがシンプルに行えそうだったので、今の環境をリセットしてPipenvへチャレンジしたいと思います。今回はそのために行った手順を掲載します

Pipenvとは

https://pipenv-ja.readthedocs.io/ja/translate-ja/

Pipenvは、手動でパッケージのインストールおよびアンインストールを行うのと同じように Pipfile に対してパッケージの追加および削除を行うのに加え、自動でプロジェクト用の仮想環境を作成し管理します。 またPipenvは、いかなるときも重要な Pipfile.lock を生成し、これを利用しビルドが常に同じ結果になるようにします。

Pipenvは主にアプリケーションのユーザーと開発者に、簡単に作業環境を作れる方法を提供するためのツールです。 ライブラリとアプリケーションの違いや、依存関係を定義するための setup.py と Pipfile の使い方の違いについては、 ? Pipfile vs setup.py を参照してください。

つまりライブラリ管理と仮想環境構築ができるということですかね

現在の環境

  • PC : macOS High Sierra MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
  • python : pyenv, pyenv-virtualenv, anaconda python自体はanaconda内に入っているものを使ってます

現在のpython環境について詳しく

$ pyenv versions
  system
* anaconda3-5.1.0 (set by /Users/ユーザ名/.pyenv/version)
  anaconda3-5.1.0/envs/ml
  anaconda3-5.1.0/envs/test

1. anaconda(python)をバージョン毎に管理

  • pyenvでanaconda(python)をバージョン毎にインストール
  • pyenv global anacondahoge(version)でバージョンを切り替え

2. anaconda(python)の各バージョンから派生し、名前で管理

  • conda create -n hoge(名前) anacondahoge(ver)でanaconda(python)を1.から派生して環境を構築
    上記コマンドによってanacondaに入ってるpythonモジュール等をフルで備えたpython環境が生成できます
    又、ケツをanacondahoge(ver)でなくpythonとすることで純粋なpython単体の環境も生成できます
  • pyenv global anacondahoge(ver)/hoge(名前)で派生した環境に切りかえる

    condaはanacondaに入っているパッケージ管理&仮想環境構築その他諸々を可能にするツールです
    2.において名前付き仮想環境をcondaで作成しているわけですが、切り替えはpyenvで行ってます
    ここで疑問としてpyenv-virtualenvが、何に対してどのように作用しているのか分かってません
    色々調べたのですが結局分からなかったので、いっそ消しちゃおうかと思ったのが今回の環境移行の動機です

    文字だとわけわかめなので図化してみる
    f:id:Atc:20180703145427j:plain

作業手順

  1. 現在のPython環境を消去(macデフォで入ってたPython2は消さない)
  2. Python3をインストール
  3. Pipenvをインストール
  4. Pipenvで仮想環境を構築&ライブラリ管理

01.現在のPython環境を消去

の前に、TimeMachineでバックアップを取っておきました
では、早速削除していきます
どういう順番で削除していくべきか...
まぁ導入したときの逆順を追っていけばいいかな...? ということで

01.の手順

01-1. condaでcreateした名前付きの各環境とpyenvで入れたanacondaを削除
01-2. pyenv-virtualenvを削除
01-3. pyenvを削除
で、イクゾー
デッデッデデデデッ


01-1. condaでcreateした名前付きの各環境を削除 anacondaの操作_参考
シェルで$ conda remove -n 名前 --allとすればよい
まずはtestから消してみる

$ conda remove -n test --all
Remove all packages in environment /Users/ユーザ名/.pyenv/versions/anaconda3-5.1.0/envs/test:

## Package Plan ##
  environment location: /Users/ユーザ名/.pyenv/versions/anaconda3-5.1.0/envs/test

The following packages will be REMOVED:

    ca-certificates: 2018.03.07-0           
    certifi:         2018.4.16-py36_0       
    libcxx:          4.0.1-h579ed51_0       
    libcxxabi:       4.0.1-hebd6815_0       
    libedit:         3.1.20170329-hb402a30_2
    libffi:          3.2.1-h475c297_4       
    ncurses:         6.1-h0a44026_0         
    openssl:         1.0.2o-h26aff7b_0      
    pip:             10.0.1-py36_0          
    python:          3.6.5-hc167b69_1       
    readline:        7.0-hc1231fa_4         
    setuptools:      39.1.0-py36_0          
    sqlite:          3.23.1-hf1716c9_0      
    tk:              8.6.7-h35a86e2_3       
    wheel:           0.31.0-py36_0          
    xz:              5.2.3-h727817e_4       
    zlib:            1.2.11-hf3cbc9b_2      

Proceed ([y]/n)? y

$ conda info -e
# conda environments:
#
base                  *  /Users/ユーザ名/.pyenv/versions/anaconda3-5.1.0
ml                       /Users/ユーザ名/.pyenv/versions/anaconda3-5.1.0/envs/ml

削除する環境の場所とパッケージが出てきた後、yを入力して消すことができた
この調子で仮想環境を全て消す
(testは純粋にpythonのみの環境なのでまだパッケージは少なかったが、anacondaを入れた環境mlはパッケージ数がめちゃくちゃ多かった) mlも削除した後、baseと書かれている環境も同様にconda removeしたら以下の通りエラー

$ conda remove -n base  --all
CondaEnvironmentError: cannot remove current environment. deactivate and run conda remove again

非アクティブ化してcondaを再度実行する...とでてきたのですが、調べてみてもよくわからなかったのと、当該環境はpyenvでインストールしたanacondaだったので、pyenvでアンインストールすればよいかと判断

$ pyenv uninstall anaconda3-5.1.0
pyenv: remove /Users/ユーザ名/.pyenv/versions/anaconda3-5.1.0?   y

$ pyenv versions
* system (set by /Users/ユーザ名/.pyenv/version)

これでmacに元々入っていたpythonだけになりました(たぶん)


01-2. pyenv-virtualenvを削除 参考

$ brew uninstall pyenv-virtualenv
Uninstalling /usr/local/Cellar/pyenv-virtualenv/1.1.1... (20 files, 60.6KB)


01-3. pyenvを削除 参考

$ which pyenv
/usr/local/bin/pyenv

$ brew uninstall pyenv
Uninstalling /usr/local/Cellar/pyenv/1.2.4... (603 files, 2.4MB)

$ which pyenv
表示なし


macに元々入っていたpythonしかないことを確認

$ which python
/usr/bin/python

OK

02. Python3をインストール The Hitchhiker’s Guide to Python

& brew install python
See: https://docs.brew.sh/Homebrew-and-Python
==> Summary
🍺  /usr/local/Cellar/python/3.7.0: 4,788 files, 102.2MB

$ which python3
/usr/local/bin/python3

$ python3 --version
Python 3.7.0

OK
Python3.7がリリースしたので最新が入りました

03. Pipenvのインストール Pipenv公式ドキュメント, 参考

$ brew install pipenv

==> Summary
🍺  /usr/local/Cellar/pipenv/2018.7.1: 1,358 files, 18.8MB

04. Pipenvで仮想環境を構築&ライブラリ管理 参考

私はカレントディレクトリの後にpytho_1という名前のディレクトリがあり、そこにpythonファイルを置いているので、ひとまずそこに移動します
その後pipenvによって仮想環境を作ります

$ cd pytho-1
$ pipenv install #仮想環境を作成
Creating a virtualenv for this project...
Pipfile: /Users/ユーザ/pytho_1/Pipfile
Using /usr/local/Cellar/pipenv/2018.7.1/libexec/bin/python3.7 (3.7.0) to create virtualenv...
⠋Already using interpreter /usr/local/Cellar/pipenv/2018.7.1/libexec/bin/python3.7
Using real prefix '/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7'
New python executable in /Users/ユーザ/.local/share/virtualenvs/pytho_1-kjK1izHD/bin/python3.7
Also creating executable in /Users/ユーザ/.local/share/virtualenvs/pytho_1-kjK1izHD/bin/python
Installing setuptools, pip, wheel...done.
Setting project for pytho_1-kjK1izHD to /Users/ユーザ/pytho_1

Virtualenv location: /Users/ユーザ/.local/share/virtualenvs/pytho_1-kjK1izHD
Creating a Pipfile for this project...
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Updated Pipfile.lock (a65489)!
Installing dependencies from Pipfile.lock (a65489)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

すると当該ディレクトリに以下のファイルが生成される

Pipfile  Pipfile.lock

中を見てみる
* Pipfile

$ cat pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]

[requires]
python_version = "3.7"

バージョンが書いてあった。よかったpython2じゃなかった
* Pipfile.lock

$ cat pipfile.lock
{
    "_meta": {
        "hash": {
            "sha256": "7e7ef69da7248742e869378f8421880cf8f0017f96d94d086813baa518a65489"
        },
        "pipfile-spec": 6,
        "requires": {
            "python_version": "3.7"
        },
        "sources": [
            {
                "name": "pypi",
                "url": "https://pypi.org/simple",
                "verify_ssl": true
            }
        ]
    },
    "default": {},
    "develop": {}
}

JSON形式になっているpipfile.lockにはパッケージが書き込まれる模様

  • 作成した環境にパッケージをインストールしてみる
$ pipenv install requests

仮想環境でpyを実行する方法

  1. 作成した仮想環境をactivateする
  2. pipenv run pythonで実行

  3. 作成した仮想環境をactivateする

$ python --version
Python 2.7.10
$ pipenv shell #仮想環境に入る
Launching subshell in virtual environment…
bash-3.2$  . /Users/ユーザ/.local/share/virtualenvs/pytho_1-kjK1izHD/bin/activate
(pytho_1-kjK1izHD) bash-3.2$ python --version
Python 3.7.0

$ cd weather_pop
$ python3 weather_pop.py

(pytho_1-kjK1izHD) bash-3.2$ exit #シェルから抜ける


2. pipenv run pythonで実行

$ pipenv run python3 #requestsがインストールされている対話モードが実行
$ pipenv run python3 weather_pop.py #weather_pop.py(requestsを用いる)が実行された

pipenvを導入して、モジュールをインストール、環境を切り替えるまではできるようになりましたが正直わからんことだらけなので勉強しなきゃ...