仮想環境作成モジュールvenvで作成した仮想環境をつかって、PyCharmで開発を行う

最近ラズパイやAWS Lambda、AIまわりでPythonをさわってますが、プロジェクト単位にpipのパッケージを管理する方法などがいろいろあるっぽくて、なかなかややこしい。
シンプルに、あとPyCharmなどのIDEと共存(?)しながら開発するにはどういう環境でやればイイのかなって、調べた内容をメモしておきます。

結論いうと、Python3系から導入されてるvenvっていう仮想環境作成モジュールが、PyCharm側も対応してるようで、それをつかってみることにしました。

[28.3. venv — 仮想環境の作成](https://docs.python.jp/3/library/venv.html) 原文も仮想環境(virtual environments) って表現してますが、独立な環境を作成できるツールって事でよさそうです。


## 今回の環境

```bash
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.1 (Mojaveです)
BuildVersion:	18B75
```

あと PyCharm は PyCharm CE 2018.2 です


## 分離された環境の構築
さて、インストールされているPythonをテンプレにして、独立したPython環境を構築します。
下記のコマンドで、指定したディレクトリ(~/venv/venv_371/) に環境を作成できます。

```bash
$ python3 -m venv ~/venv/venv_371/
```

この環境を、いまのこのコンソールで使用するために、下記のコマンドを実行します。

```bash
$ source ~/venv/venv_371/bin/activate
(venv_371) $ which python3
/Users/xxx/venv/venv_371/bin/python3
(venv_371) $ 
```

このコンソールが上記のPython環境をつかうようになりました。それを示すために、シェルの先頭に(venv_371) って仮想環境名が表示されているのがわかると思います。

終了するには以下のコマンドで。

```bash
(venv_371) $ deactivate
$ which python3
/Users/xxx/.pyenv/shims/python3
$
```

元に戻りました。

さて初めにも書きましたが、この**仮想環境を作成する目的は、pipなどでパッケージをinstall/update した際に、他の開発者の環境に影響しないように、プロジェクト単位で開発/稼働環境を分離すること**です。

実際、たとえば下記のようにrequestsパッケージをインストールしたときに

```bash
$ source ~/venv/venv_371/bin/activate
(venv_371) $ pip install requests
(venv_371) $ pip freeze
certifi==2018.10.15
chardet==3.0.4
idna==2.7
requests==2.20.1
urllib3==1.24.1

(venv_371) $ deactivate
$ pip freeze
$
```

てできますよ、ってことです。もとのPython環境にはpipで入れたパッケージ達はインストールされていません。便利ですね。

この、全体をまるっとコピーして環境を分離するっていう仕組み(考え方?)が始めわかんなくて。わかんなくてって言うのは、たとえばJavaでもMavenでプロジェクト単位に都度ライブラリを指定するだけだし、nodejsもnpmでglobalにはインストールしないでcurrentディレクトリにインストールすればOKなわけで。インタプリタごとコピーするって、なかなか大胆ですよね。

Pythonをつかってまもなくは、Mavenやnpmらと同じ感覚で

```bash
sudo pip3 install -r requirement.txt -t ./
```

ってカレントにインストールすればイイのかなって思ってたんですね。実際AWS Lambdaにアップするときはそうしますし。でも、カレントディレクトリに直接いろいろ展開されて、ディレクトリが汚れてしまって、どうも気になってたんですよね、、。Pythonの環境を分ける考え方は、globalに入れるオペをするけど、そもそもglobal自体が分離されているってことでした。

ちなみに、さきの

```bash
$ python3 -m venv ~/venv/venv_371/
```
を

```bash
$ python3 -m venv ~/venv/venv_371/ --system-site-packages
```

とすると、テンプレ元のPythonにインストールされているパッケージまで引き連れて、仮想環境を作成するようです。Anacondaとかをつかうときとかは、パッケージまでコピーしたいでしょうから上記のオプションを指定する、そんな感じですかね。。




**2018/12/31追記**

--system-site-packages は Anacondaとかでつかうかな？って書きましたが、AnacondaなPythonには仮想環境を作成する専用コマンドがあるようです。

```bash

$ pyenv versions
* anaconda3-5.3.0 (set by /Users/xxxx/.pyenv/version)

$ conda create --name my_anaconda  python=3.6
Solving environment: done
  environment location: /Users/xxxx/.pyenv/versions/anaconda3-5.3.0/envs/my_anaconda
  ...

Proceed ([y]/n)? y

Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use:
# > source activate my_anaconda
#
# To deactivate an active environment, use:
# > source deactivate
```

ものすごく時間がかかりますorz。

activateですが環境によっては(pyenvだとかな？)パスが通ってないぽく、

```bash
$ source ~/.pyenv/versions/anaconda3-5.3.0/bin/activate my_anaconda
(my_anaconda) $
```

ってしましょう。deactivateは

```bash
(my_anaconda) $ source ~/.pyenv/versions/anaconda3-5.3.0/bin/deactivate
$
```

これで。。
**2018/12/31追記 ここまで**









## PyCharmの話

さてそろそろPyCharmですが、新規でプロジェクトを作成する際、もしくはあとでも可能ですが、実はウラで環境(Environment)を指定しています。
実際にPyCharm上で、先ほど作成した仮想環境を適用してみようと思います。

### さっきの分離環境をPyCharmからつかう

PyCharmでプロジェクトを作成します。ProjectのInterpreterを選択できるので、▼をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/acb821d8-4049-2b02-6b1f-2530c1cfb762.png)


Existing Interpreterを選択し、右部のダイアログを開くボタンをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/1a8a050e-7b99-e8e5-53dc-3467b0acbdfd.png)

Interpreterを選択する画面になるので、右部のダイアログを開くボタンをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/faffd317-c1b4-5f1a-b506-d5641bcf8815.png)


先ほどの、仮想環境のディレクトリ `~/venv/venv_371/`の下の、`bin/python` を選択してOKをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/7e69b256-26c4-6eb2-3c75-baf3e3d6c186.png)

使用するInterpreterが、先の仮想環境のPythonになりました。OKをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/d8d4bd91-dae9-106b-5bfc-f6d89064b763.png)


使用するInterpreterを切り替えました。再度プロジェクト作成画面にもどるので、プロジェクトを配置する場所を指定し、InterpreterをExisting Interpreter として、先の仮想環境が選べていることを確認し、Createをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/483170b8-c32d-9e52-05ce-85a7791c954f.png)

プロジェクトが作成されました！

ライブラリのところ見てみると、先ほどpipした内容が反映されていますね。。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/1d88f992-de04-3a12-da43-17ad8edbc876.png)


PyCharmのターミナルを起動してみると、すでに仮想環境がactivateされていて、`pip freeze` してみても、、、ちゃんと仮想環境になってることが確認出来ますね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/0847d668-5556-470b-1dac-98643c0b9047.png)

以上で venvで作成した仮想環境をPyCharmから使用することが出来ました。


### PyCharmで新規の仮想環境を作って、ターミナルからつかう
逆に、PyCharmで新規作成した仮想環境をターミナルからつかうことも可能です。
プロジェクトを新規作成し、▼をクリックして仮想環境の詳細設定を開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/92e774d2-1748-cd32-6c62-86132a8c16bd.png)
今回、PyCharm上で新規に仮想環境を作成するので、「New environment using Virtualenv 」を選択、Locationは `~/venv/newProject2`としました。ベースとなるInterpreterを選べるのですが、デフォルトのモノ(ココでは`~/.pyenv/versions/3.7.1/bin/python`)を使用しました。

さいごに「Inherit global site-packages」のチェックですが、先にでてきた`--system-site-packages`の可否に該当するようなのですが、どうもチェックを入れるとpipだけオリジナルのpipを参照してしまう(?)ようで、つまり下記の通りになってしまうので、、

```bash
$ source ~/venv/newProject2/bin/activate
(newProject2) $ which pip
/Users/xxxx/.pyenv/shims/pip   ←!!
(newProject2) $ which python
/Users/xxxx/venv/newProject2/bin/python
(newProject2) $
```

**今回はチェックを外すことにしました。**

参考: [Virtualenv環境の設定](https://pleiades.io/help/pycharm/creating-virtual-environment.html)
ココにも「--system-site-packages オプションに対応します。」って書いてあるんですけどね。わたし固有の環境だけでしょうか、、、。

最後にCreateをクリックしてプロジェクトを作成します。


無事、プロジェクトが作成されました。PyCharmのターミナルを見ても、newProject2という仮想環境が作成できているようです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73777/efdda203-f9f7-9327-74e8-23c2119be980.png)

上記の通り、こんどは pip でbeautifulsoup4 を入れてみたので、またまたMacのターミナルで確認してみます。

```bash
$ which python
/Users/xxxx/.pyenv/shims/python
$ ls -lrt ~/venv/newProject2/
total 8
drwxr-xr-x  2 xxxx  staff   64 Nov 13 12:03 include
drwxr-xr-x  3 xxxx  staff   96 Nov 13 12:03 lib
drwxr-xr-x  7 xxxx  staff  224 Nov 13 12:03 bin
-rw-r--r--  1 xxxx  staff  102 Nov 13 12:03 pyvenv.cfg

$ source ~/venv/newProject2/bin/activate
(newProject2) $ which python
/Users/xxxx/venv/newProject2/bin/python

(newProject2) $ pip3 freeze
beautifulsoup4==4.6.3
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

(newProject2) $ deactivate
$
```

OKそうですね。

## Windowsのばあい
今回 Macでやりましたが、venvはもちろんWindowsでも可能です。ただ微妙にコマンドとパスが異なるようで、

```bash
c:\xxxxx\[venv_dir]\Scripts\activate.bat
```

となることにご注意ください。


## Inherit global site-packages の件

さきほどの Inherit global site-packages の件ですが、チェックを入れていると、どうも仮想環境にpipなどのコマンドがコピーされないようで、、。

```bash
$ ls -lrt ~/venv/venv_from_command/bin/
total 64
lrwxr-xr-x  1 xxxx  staff    50 Nov 13 13:57 python3 -> /Users/xxxx/.pyenv/versions/3.7.1/bin/python3
lrwxr-xr-x  1 xxxx  staff     7 Nov 13 13:57 python -> python3
-rwxr-xr-x  1 xxxx  staff   269 Nov 13 13:57 easy_install
-rwxr-xr-x  1 xxxx  staff   269 Nov 13 13:57 easy_install-3.7
-rwxr-xr-x  1 xxxx  staff   251 Nov 13 13:57 pip
-rwxr-xr-x  1 xxxx  staff   251 Nov 13 13:57 pip3
-rwxr-xr-x  1 xxxx  staff   251 Nov 13 13:57 pip3.7
-rw-r--r--  1 xxxx  staff  2449 Nov 13 13:57 activate.fish
-rw-r--r--  1 xxxx  staff  1297 Nov 13 13:57 activate.csh
-rw-r--r--  1 xxxx  staff  2241 Nov 13 13:57 activate
```

に対し

```bash
$ ls -lrt ~/venv/venv_from_pycharm/bin/
total 13016
-rwxr-xr-x  1 xxxx  staff  3323712 Nov 13 13:59 python
-rwxr-xr-x  1 xxxx  staff  3323712 Nov 13 13:59 python3
-rw-r--r--  1 xxxx  staff     2449 Nov 13 13:59 activate.fish
-rw-r--r--  1 xxxx  staff     1297 Nov 13 13:59 activate.csh
-rw-r--r--  1 xxxx  staff     2241 Nov 13 13:59 activate
$
```

となってます、、。だからpipのパスがオリジナルを指してたんですね、、、。ちなみにWindowsのPyCharmでもおなじでした、、、。原因は不明。とりあえずなんとかしたいですが、、、まあ `--system-site-packages` つけたいときは、とりあえずターミナルから仮想環境を作成することにします。

識者のかた、おしえてください。。



## まとめ

Python3 には、仮想環境を作成するvenvというツールがあり、venvをつかうことで、パッケージをプロジェクト毎に分離出来ることが分かりました。またvenvは、一部自分では解決できなかった制約があるものの、コマンドから実行するなど回避可能なものだし、基本はPyCharm 上からも操作可能であることが分かりました。コレで心置きなくpipでパッケージを出し入れしながらPyCharmで開発が始められそうです。

Pythonおもしろいですね。。
おつかれさまでした。


## 関連リンク
- [28.3. venv — 仮想環境の作成](https://docs.python.jp/3/library/venv.html) 
- [venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)
- [pyenvが必要かどうかフローチャート](https://qiita.com/shibukawa/items/0daab479a2fd2cb8a0e7) 
- [仮想環境](https://www.python.jp/install/windows/virtualenv.html) Pythonコミュニティのドキュメント。わかりやすい。
- [pyenv-virtualenvでディレクトリ単位のpython環境構築](https://qiita.com/niwak2/items/5490607be32202ce1314) pyenv-virtualenvとvenvは別モノなんですね、、乱立していて初心者にはややこしいです